SpringBoot defines an elegant and globally unified Restful API response framework, completes the “Spreading Flowers” chapter, and encapsulates the starter component

We have published a series of articles before. Explain how to seal the unified global response Restful API.

If you are interested, you can read my previous articles (the entire starter project development history)

SpringBoot defines an elegant and globally unified Restful API response framework [1]

SpringBoot defines an elegant and globally unified Restful API response framework 2 [2]

SpringBoot defines an elegant and globally unified Restful API response framework 3 [3]

SpringBoot defines an elegant and globally unified Restful API response framework 4 [4]

SpringBoot defines an elegant and globally unified Restful API response framework 5 [5]

SpringBoot defines an elegant and globally unified Restful API response framework 6 [6]

Later, I came up with a new idea. SpringBoot does not provide its own starter. Can we also customize starter, so I defined rest-api-spring-boot-starter, which has been published to the maven central warehouse, and is based on the previous Restful API response framework Integration and refactoring,

On this basis, I have summarized and encapsulated many tools that are commonly used in my own work, and combined with SpringBoot to encapsulate all-round tools. It has been updated to 1.3.0 and does not couple any dependencies. Please use the latest version.

The current updated version 1.3.0 has the following functions:

  1. Supports one-click configuration of customized RestFull API unified format return

  2. Support RestFull API error internationalization

  3. Support global exception handling and global parameter verification processing

  4. Business error assertion tool encapsulation, following the error priority return principle

  5. redis work package. Supports all key operation tools

  6. RestTemplate encapsulates POST and GET request tools

  7. Log integration. Customize the log path, classify it according to the log level, support compression and file size splitting. Show by time

  8. Tool library integration integrates lombok, hutool, commons-lang3, and guava. No need to import it individually

  9. Integrate mybatisPlus one-click code generation

github address[7]

Next I will talk about how to use it in the project

Let’s create a new SpringBoot Web project

We just need to introduce it in pom

 <dependency>
            <groupId>cn.soboys</groupId>
            <artifactId>rest-api-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

Just add the @EnableRestFullApi annotation to the startup class or configuration class.

In this way, in the project controller we write ordinary requests such as:

 @PostMapping("/chat")
    public HashMap chatDialogue() {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

What is returned is the global unified RestFull API

We can also write this

Many return methods are provided.

Of course, if you don’t want to wrap this interface into a global return and want to customize a separate return, we only need to add the @NoRestFulApi annotation to the method.

 @PostMapping("/chat")
    @NoRestFulApi
    public HashMap chatDialogue() {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

There will be no packaging of the returned content.

Helps you encapsulate all common HTTP errors, as well as all request type and parameter errors.

Such as request error

{
    "success": false,
    "code": "405",
    "msg": "Method not allowed",
    "timestamp": "2023-07-03 22:36:47",
    "data": "Request method 'GET' not supported"
}

The requested resource does not exist

{
    "success": false,
    "code": "404",
    "msg": "The requested resource does not exist",
    "timestamp": "2023-07-03 22:42:35",
    "data": "/api"
}

Parameter verification error

Verify Student object parameters

 * @author public account programmer three hours
 * @version 1.0
 * @date 2023/6/26 22:10
 * @webSite https://github.com/coder-amiao
 */
@Data
public class Student {
    @NotBlank
    private String nam;
    @NotBlank
    private String hobby;
}

 @PostMapping("/chat")
    public HashMap chatDialogue(@Validated Student student) {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

Request results

JSON Body parameters

 @PostMapping("/chat")
    public HashMap chatDialogue(@RequestBody @Validated Student student) {
        HashMap m = new HashMap();
        m.put("age", 26);
        m.put("name", "Judy");
        return m;
    }

The built-in encapsulation error supports both English and Chinese internationalization by default. You don’t do any configuration to automatically support

If you need built-in support for more languages, just overwrite it.

Customize your own error internationalization and language

i18n:
    
    i18n-header: Lang
    default-lang:cn
    message:
      
      internal_server_error:
        en: Internal Server Error
        cn: system error
      not_found:
        en: Not Found
        cn: The requested resource does not exist

message corresponds to the error prompt and corresponds to internal_server_error. Customize the following language. Define it by yourself. Correspond to the i18n-header passed in from the front end, and the error language you define will be displayed.

If I don’t send an error, the internationalization default is Chinese and is configured in default-lang: cn

When I pass in the specified language, an error message will be returned according to the internationalization customization you configured.

If my built-in errors cannot meet your business needs, you can also customize your own error codes.

You only need to implement the ResultCode interface to customize the error enumeration

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;


 * @author public account Programmer Sanshi
 * @version 1.0
 * @date 2023/6/26 10:21
 * @webSite https://github.com/coder-amiao
 * Response code interface, customize response code, implement this interface
 */
public interface ResultCode extends I18NKey {

    String getCode();

    String getMessage();

}

If you want to support internationalization, you also need to implement the internationalization interface I18NKey. Just refer to my internal HttpStatus implementation.

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;


 * @author public account Programmer Sanshi
 * @version 1.0
 * @date 2023/6/26 11:01
 * @webSite https://github.com/coder-amiao
 */
public enum HttpStatus implements ResultCode, I18NKey {
    
     * Internal System Error
     */
    INTERNAL_SERVER_ERROR("500", "internal_server_error"),
    BAD_GATEWAY("502", "bad_gateway"),
    NOT_FOUND("404", "not_found"),
    UNAUTHORIZED("401", "unauthorized"),
    FORBIDDEN("403", "forbidden"),
    METHOD_NOT_ALLOWED("405", "method_not_allowed"),
    REQUEST_TIMEOUT("408", "request_timeout"),

    INVALID_ARGUMENT("10000", "invalid_argument"),
    ARGUMENT_ANALYZE("10001", "argument_analyze"),
    BUSINESS_EXCEPTION("20000", "business_exception");


    private final String value;

    private final String message;

    HttpStatus(String value, String message) {
        this.value = value;
        this.message = message;
    }


    @Override
    public String getCode() {
        return value;
    }

    @Override
    public String getMessage() {
        return message;
    }


    @Override
    public String key() {
        return message;
    }
}



rest-api:
  enabled: false
  i18n:
    
    i18n-header: Lang
    default-lang:cn
    message:
      
      internal_server_error:
        en: Internal Server Error
        cn: system error
      bad_gateway:
        en: Bad Gateway
        cn: Bad request
      unauthorized:
        en: Unauthorized
        cn: Unauthorized
      forbidden:
        en: Forbidden
        cn: Access to resources is prohibited
      method_not_allowed:
        en: Method Not Allowed
        cn: method not allowed
      request_timeout:
        en: Request Timeout
        cn: Request timeout
      invalid_argument:
        en: Invalid Argument {}
        cn: Parameter error {}
      argument_analyze:
        en: Argument Analyze {}
        cn: Parameter parsing exception {}
      business_exception:
        en: Business Exception
        cn: business error
      not_found:
        en: Not Found
        cn: The requested resource does not exist


Internal errors do not require any configuration and internationalization is automatically supported. If you need to support more languages, you can customize it for coverage.

In project development, we sometimes need to encapsulate our own exception classes. I have encapsulated a unified error exception class. BusinessException has implemented global error interception for business exception classes.

Encapsulates a unified business exception assertion tool and follows the error priority return principle. Code is more elegant

 @GetMapping("/exception")
    public Result exception(){
        Student s=null;
        Assert.isFalse(s==null,"Student cannot be null");
        return Result.buildSuccess();
    }

Throw unified business exception

Of course if you want to define your own exception class. You can define your own exception class·Inherit my BusinessException

Further encapsulation of Redis related key and value operations is performed when using the redis tool library. we need to introduce

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

By default, it will not be imported for you.

Then just inject it when using it

@Autowired
    private RedisTempUtil redisTempUtil;

 @GetMapping("/redis")
    public Result redis() {
        redisTempUtil.set("test", "123456");
        return Result.buildSuccess();
    }


    @GetMapping("/redis/get")
    public Result redisGet() {
        String value = redisTempUtil.get("test").toString();
        log.info("redis value{}", value);
        return Result.buildSuccess();
    }

Further encapsulates RestTemplate requests and injects them when used in Post and GET projects

 @Autowired
    private RestFulTemp restFulTemp;

 @GetMapping("/doGet")
    public Result doGet() {
        ResponseEntity<String> response = restFulTemp.doGet("http://127.0.0.1:8000/redis/get");
        return Result.buildSuccess(response.getBody());
    }

Further encapsulates log processing to enable out-of-the-box use. Just configure the relevant log configuration in the properties file

rest-api:
  enabled: false
  logging:
    path: ./logs
    max-history: 90
    max-file-size: 3MB
    max-total-size-cap: 1GB
    level-root: INFO

If your properties file does not configure any logs, the default logs will be configured as above.

In the project, we will frequently use mybatisPlus, but we can generate simple template code with just one click. By default, it does not depend on any related packages of mybatisPlus. If you need to use automatic code generation, just introduce the mybatisPlus code generation dependency package.

 <!--Generator dependencies-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
            <optional>true</optional>
        </dependency>
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
            <optional>true</optional>
        </dependency>
        <!--Template engine that code generation relies on-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
            <optional>true</optional>
        </dependency>

You can directly write the test class and then directly call the code generation

public class Test {
    public static void main(String[] args) {
        GenerateCodeConfig config=new GenerateCodeConfig();
        config.setDriverName("com.mysql.cj.jdbc.Driver");
        config.setUsername("root");
        config.setPassword("root");
        config.setUrl("jdbc:mysql://127.0.0.1:3306/ry?useUnicode=true & amp;useSSL=false & amp;characterEncoding=utf8");
        
        config.setProjectPath("superaide");
        config.setPackages("cn.soboys.superaide");
        MyBatisPlusGenerator.generate(config);
    }
}


The effect is as follows

Follow the public account, Programmer Sanshi will continue to output high-quality content, hoping to bring you some inspiration and help

The next article will explain this source code analysis and how to encapsulate your own stater

Reference materials

[1]

https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ== & amp;mid=2247483741 & amp;idx=1 & amp;sn=2734d2ef008edcf1369dd7a31a88a142 & amp;chksm=cfe5f27bf8927b6d468a411fe2 eaeeeb6dbdd5527dec77a77a0e580ea32b2b58f38922836552#rd: https ://link.juejin.cn/?target=https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ==&mid=2247483741&idx=1&sn=2734d2ef008edcf1369dd7a31a88a142&chksm=cfe5f27bf8927b6d468a411 fe2eaeeeb6dbdd5527dec77a77a0e580ea32b2b58f38922836552#rd

[2]

https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ== & amp;mid=2247483752 & amp;idx=1 & amp;sn=eab94282e3f1e62682d2106cfb2949d1 & amp;chksm=cfe5f24ef8927b582e018638 81a88452dcbcb102afdb9b50985304b97dfd74cd0c3ed0b8c2c3#rd: https ://link.juejin.cn/?target=https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ==&mid=2247483752&idx=1&sn=eab94282e3f1e62682d2106cfb2949d1&chksm=cfe5f24ef8927b582e0186 3881a88452dcbcb102afdb9b50985304b97dfd74cd0c3ed0b8c2c3#rd

[3]

https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ== & amp;mid=2247483761 & amp;idx=1 & amp;sn=dbc516d0ba14228c1f091dfa39d85209 & amp;chksm=cfe5f257f8927b41635fe150 8c2829d73e2b788105b145bc51525be4574b83a1a8da23c49ec2#rd: https ://link.juejin.cn/?target=https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ==&mid=2247483761&idx=1&sn=dbc516d0ba14228c1f091dfa39d85209&chksm=cfe5f257f8927b41635fe1 508c2829d73e2b788105b145bc51525be4574b83a1a8da23c49ec2#rd

[4]

https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ== & amp;mid=2247483887 & amp;idx=1 & amp;sn=cb737d573adca7eaea7a59cad2a7bbfe & amp;chksm=cfe5f2c9f8927bdfaf7e46fd38d26f 56fffbb1ece8460eaffe2addee592e42ffee6ba49530b7#rd:https ://link.juejin.cn/?target=https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ==&mid=2247483887&idx=1&sn=cb737d573adca7eaea7a59cad2a7bbfe&chksm=cfe5f2c9f8927bdfaf7e46fd38d2 6f56fffbb1ece8460eaffe2addee592e42ffee6ba49530b7#rd

[5]

https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ== & amp;mid=2247484102 & amp;idx=1 & amp;sn=e17772a12e6548755c341c2d9300e235 & amp;chksm=cfe5f1e0f89278f669c4c 89548b3fdeec4dd58d6d7d7580315d07f20c9b52ffdd21ef5a7c232 &token=691863430 & amp;lang=zh_CN#rd: https://link.juejin.cn/?target=https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ==&mid=2247484102&idx=1&sn=e17772a12e6548755c341c2d9300e235&chksm =cfe5f1e0f89278f669c4c89548b3fdeec4dd58d6d7d7580315d07f20c9b52ffdd21ef5a7c232&token=691863430&lang=zh_CN#rd

[6]

https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ== & amp;mid=2247484160 & amp;idx=1 & amp;sn=37eea0079dd175634437f01dde38bb4c & amp;chksm=cfe5f026f892793045fb242a5 56ce4e3010f4a4aae867a84fe3542ed18ac3c64b85e87fa536a#rd: https ://link.juejin.cn/?target=https://mp.weixin.qq.com/s?__biz=Mzg4OTkwNjc2MQ==&mid=2247484160&idx=1&sn=37eea0079dd175634437f01dde38bb4c&chksm=cfe5f026f892793045fb242 a556ce4e3010f4a4aae867a84fe3542ed18ac3c64b85e87fa536a#rd

[7]

https://github.com/coder-amiao/rest-api-spring-boot-starter: https://link.juejin.cn/?target=https://github.com/coder-amiao/ rest-api-spring-boot-starter

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 138221 people are learning the system