3

Spring Boot 功能整合

 2 years ago
source link: https://iiong.com/spring-boot-function-integration/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

0x0 前言

如果根据之前做的 Nest.js 后端项目功能为标准的话,那么 Spring Boot 项目需要几种功能进行整合,好在生态丰富,集成也不算困难。所以打算根据之前的项目使用 Spring Boot 重写个新的项目:

  • Restful API CRUD 功能实现
  • 数据库对象关系映射功能持久化支持
  • OpenAPI 文档支持
  • 参数校验判断业务
  • redis 缓存

0x1 数据库持久化支持

目前数据库持久化主要是 Spring Boot JpaSpring Boot Mybatis 。如果看过 JPA 的业务过程会发现和 Nodejs 中的 TypeORM 及其相似。Mybatis 主要可以灵活调试动态 Sql 。不管怎么说根据自己项目业务需求选定其中功能吧。

安装 MyBatis 教程可以官方文档查阅:mybatis-spring-boot-autoconfigure

0x2 Swagger 文档支持

集成 Swagger UI 文档支持也非常简单,生态中的 springfox 做的不错,添加依赖:

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-boot-starter</artifactId>
  <version>3.0.0</version>
</dependency>

这里需要指定版本,不指定拉取依赖会报错。

然后在启动方法添加注解:

@EnableOpenApi
public class YasuoApplication {
	public static void main(String[] args) {
    // ...
	}
}

然后在 Controller 类上添加标识:

@Api(value = "global", tags = "全局接口")
@RestController
@RequestMapping("/")
public class AppController {
}

在然后在方法里添加详细信息:

@Api(value = "global", tags = "全局接口")
@RestController
@RequestMapping("/")
public class AppController {
    UserService userService;

    @ApiOperation(value = "用户登录", notes = "系统用户登录")
    @PostMapping("login")
    public JSONObject login(@RequestParam("username") String username, @RequestParam("password") String password) {
        System.out.println(username);
        System.out.println(password);
        JSONObject info = new JSONObject();
        return info;
    }
}

启动项目访问:http://localhost:8080/swagger-ui 即可访问。值得注意是如果你在 application 添加 server.servlet.contextPath 选项的时候记得添加对应的字段。

0x3 参数校验 JSR303

springboot-2.3 开始,校验包被独立成了一个 starter 组件:

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

比如在 DTO 类里:

package com.iiong.yasuo.dto;

import lombok.Data;

import javax.validation.constraints.NotEmpty;

/**
 * Author: Jaxson
 * Description: 请求用户登录参数
 * Date: 2021-05-26
 */
@Data
public class UserLoginRequestDTO {
    @NotEmpty(message = "登录名称不得为空!")
    private String username;

    @NotEmpty(message = "登录密码不得为空!")
    private String password;
}

内置的校验注解可以查看官方文档,然后进行参数校验:

@ApiOperation(value = "用户登录", notes = "系统用户登录")
@PostMapping("login")
public RestfulModel<UserLoginResponseDTO> login(@RequestBody @Validated UserLoginRequestDTO userLoginRequestDTO) {
    System.out.println(userLoginRequestDTO);
    UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO();
    userLoginResponseDTO.setId(1013401346173L);
    userLoginResponseDTO.setLoginName("112233");
    userLoginResponseDTO.setName("系统管理员");
    userLoginResponseDTO.setToken("test");
    return new RestfulModel<>(0, "登录成功!", userLoginResponseDTO);
}

不过默认返回的异常信息并不是很友好,需要再次简化,所以需要做个全局异常处理。如果需要可以使用 @RestControllerAdvice 注解来表示全局处理类:

/**
 * Author: Jaxson
 * Description: 全局异常处理类
 * Date: 2021-05-26
 */
@ControllerAdvice
public class ExceptionHandlerConfig {

    /**
     * 统一处理参数校验异常
     * @param bindException 捕捉到的异常
     * @return 返回数据
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public RestfulModel<Object> validExceptionHandler(BindException bindException) {
        String exceptionMsg = bindException.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        return new RestfulModel<>(1000, exceptionMsg, null);
    }
}

当然这里面还可以处理一些系统级别的异常,自己抛出即可。

0x4 跨域解决

解决跨域问题也很简单,只需要实现接口 WebMvcConfigurer 重写方法即可:

/**
 * Author: Jaxson
 * Description: 运行跨域
 * Date: 2021-05-26
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry corsRegistry) {
        corsRegistry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedHeaders(CorsConfiguration.ALL)
                .allowedMethods(CorsConfiguration.ALL)
                .allowCredentials(true)
                .maxAge(3600); // 1小时内不需要再预检(发OPTIONS请求)
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK