SpringBoot defines an elegant and globally unified Restful API response framework Ends the Sprinkle Chapter Encapsulates the starter component

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

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

SpringBoot defines an elegant global unified Restful API response framework

SpringBoot defines an elegant global unified Restful API response framework 2

SpringBoot defines an elegant global unified Restful API response framework three

SpringBoot defines an elegant global unified Restful API response framework four

SpringBoot defines an elegant global unified Restful API response framework five

SpringBoot defines an elegant global unified Restful API response framework six

Later, I came up with a new idea, SpringBoot did not provide its own starter. Can we also customize the starter , so I defined rest-api-spring-boot-starter , which has been released to the maven central warehouse, and has integrated and refactored the previous Restful API response framework.

On this basis, I summarized and encapsulated many tools commonly used in my own work, combined with SpringBoot to encapsulate almighty tools. It has been updated to 1.3.0 without coupling any dependencies, please use the latest version

The current updated version 1.3.0 features are as follows

  1. Support one-click configuration to customize RestFull API uniform format return
  2. Support RestFull API error internationalization
  3. Support global exception handling, global parameter verification processing
  4. Encapsulation of business error assertion tools, following the principle of returning errors first
  5. redis working package. Support all key operation tools
  6. RestTemplate encapsulates POST, GET request tool
  7. Log integration. Customize the log path, classify according to the log level, support compression and file size segmentation. display by time
  8. The tool library integrates lombok, hutool, commons-lang3, and guava. No need to import them individually
  9. Integrated mybatisPlus one-click code generation

github address

Let me talk about how to use it in the project

We create a new SpringBoot Web project

We just need to import it in pom

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

@EnableRestFullApiJust add annotations to the startup class or configuration class

RestFull API usage

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

Many return methods are provided.

@NoRestFulApiOf course, if you don’t want to wrap this interface into a global return, if you want to customize a separate return, for example , we only need to add annotations to the method

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

No wrapping will be performed on the returned content.

Global error interception, parameter verification

Help you encapsulate all common http errors, and all request type and parameter errors.

If the request is wrong

{
    
    
    "success": false,
    "code": "405",
    "msg": "方法不被允许",
    "timestamp": "2023-07-03 22:36:47",
    "data": "Request method 'GET' not supported"
}

The requested resource does not exist

{
    
    
    "success": false,
    "code": "404",
    "msg": "请求资源不存在",
    "timestamp": "2023-07-03 22:42:35",
    "data": "/api"
}

Parameter validation error

Validate Studen object parameters

/**
 * @author 公众号 程序员三时
 * @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 result

JSON Body parameter

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

wrong internationalization

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

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

Customize your own error internationalization and language

  i18n:
    # 若前端无header传参则返回中文信息
    i18n-header: Lang
    default-lang: cn
    message:
      # admin
      internal_server_error:
        en: Internal Server Error
        cn: 系统错误
      not_found:
        en: Not Found
        cn: 请求资源不存在

message corresponds to the error prompt
and corresponds to internal_server_error customization.
The following language is defined by yourself and the front-end passes in the i18n-header. It will show that you have defined the wrong language

I don't pass the error. The default internationalization is Chinese. Configure it in default-lang: cn

When I pass in the specified language, it will return an error message according to the internationalization customization you configured

custom error response

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 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/26 10:21
 * @webSite https://github.com/coder-amiao
 * 响应码接口,自定义响应码,实现此接口
 */
public interface ResultCode extends I18NKey {
    
    

    String getCode();

    String getMessage();

}

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

package cn.soboys.restapispringbootstarter;

import cn.soboys.restapispringbootstarter.i18n.I18NKey;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/26 11:01
 * @webSite https://github.com/coder-amiao
 */
public enum HttpStatus implements ResultCode, I18NKey {
    
    
    /**
     * 系统内部错误
     */
    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:
    # 若前端无header传参则返回中文信息
    i18n-header: Lang
    default-lang: cn
    message:
      # admin
      internal_server_error:
        en: Internal Server Error
        cn: 系统错误
      bad_gateway:
        en: Bad Gateway
        cn: 错误的请求
      unauthorized:
        en: Unauthorized
        cn: 未授权
      forbidden:
        en: Forbidden
        cn: 资源禁止访问
      method_not_allowed:
        en: Method Not Allowed
        cn: 方法不被允许
      request_timeout:
        en: Request Timeout
        cn: 请求超时
      invalid_argument:
        en: Invalid Argument {
    
    }
        cn: 参数错误 {
    
    }
      argument_analyze:
        en: Argument Analyze {
    
    }
        cn: 参数解析异常 {
    
    }
      business_exception:
        en: Business Exception
        cn: 业务错误
      not_found:
        en: Not Found
        cn: 请求资源不存在

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

business exception assertion

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

Encapsulates a unified business exception assertion tool, and follows the principle of returning errors first. more elegant code

    @GetMapping("/exception")
    public Result exception(){
    
    
        Student s=null;
        Assert.isFalse(s==null,"学生不能为空");
        return Result.buildSuccess();
    }

Throw uniform business exception

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

Redis tool library uses

Further encapsulates all relevant key and value operations on Redis when using the redis tool library. we need to import

 <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 you use 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);
        return Result.buildSuccess();
    }

RestTemplate request tool

Further encapsulates the RestTemplate request for
injection 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());
    }

log usage

Further encapsulates the log processing to achieve out-of-the-box. Configure the relevant log configuration in the property file

rest-api:
  enabled: false
  logging:
    path: ./logs   #日志存储路径(服务器上绝对)
    max-history: 90 # 保存多少天
    max-file-size: 3MB  # 每个文件大小
    max-total-size-cap: 1GB  #总文件大小超过多少压缩
    level-root: INFO    # 这里的INFO可以替换为其他日志等级,如DEBUG, WARN, ERROR, TRACE, FATAL, OFF等。 日志等级由低到高分别是debugger-info-warn-error

If your property file does not do any log configuration, the default log is configured as above.

Integrated mybatisPlus one-click code generation

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

 <!--生成器依赖-->
        <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>
        <!--代码生成依赖的模板引擎-->
        <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&useSSL=false&characterEncoding=utf8");
        //生成代码保存路径,不设置就是当前项目下路径,如何设置请使用绝对路径
        config.setProjectPath("superaide");
        config.setPackages("cn.soboys.superaide");
        MyBatisPlusGenerator.generate(config);
    }
}

The effect is as follows

Pay attention to the official account, the programmer will continue to output high-quality content at three o'clock , hoping to bring you some inspiration and help

The next article analyzes this source code and explains how to encapsulate your own stater

Guess you like

Origin blog.csdn.net/u011738045/article/details/131568151