Skip to content

app-spring-boot-starter

用于开发web应用的 springboot starter,在 快速开始 中已经使用过它,下面来详细介绍它的一些特性和用法.

版本更新

1.4.0-SNAPSHOT

  • 完善了Response Advice 部分,移除了 Resp 类,增加功能:可定制响应码、自定义异常等
  • 增加方法记录切面,可以对方法的名称、参数、返回值、耗时进行日志打印输出
  • 重写了本地限流实现
  • 集成 jasypt 实现springboot配置项的字符串加密

1.3.0-SNAPSHOT

  • 接口文档升级到 openapi3 规范,引入了 springdoc, 配置项有所改变,代码中的swagger注解需要切换到 v3 规范

接口在线文档

组件内引入了开源的 knife4j 在线文档组件,所以服务启动后,可通过 ip:port/doc.html 访问在线文档,大概长这样:

在线文档截图

如何禁用

yaml
springdoc:
  swagger-ui:
    enabled: false
  api-docs:
    enabled: false

INFO

默认是启用的,无需设置

如何添加安全认证

yaml
application:
  openapi:
    basic:
      enabled: true
      username: demo
      password: Demo@1234

TIP

出于安全考虑,推荐所有线上服务都开启此配置

定制展示信息

yaml
application:
  openapi:
    info:
      title: Sample Api
      description: "**示例接口描述**"
      version: v1.0
      contact:
        name: alex
      license: GPL-3.0
      terms-of-service-url: https://stackoverflow.com/

指定 URL 加上 Authorization 头

yaml
application:
  openapi:
    info:
      title: Varok Main Service
      description: xx数据服务
      version: 1.2.0
    auth-paths: '.*/(admin|tp|metric|dash|ui|geocache)/.*'

注: 这里的 path 支持java正则表达式

排除指定接口或包

排除指定url:

yaml
springdoc:
 paths-to-exclude: /test/**,/demo/v1/**

也可以在代码中使用注解隐藏某个接口 @Operation(summary = "演示xxx", hidden = true)

排除特定包:

yaml
springdoc:
  packages-to-exclude: com.example.internal

如果是只想开启某些url 或 package 只需要把 exclude 换成 match

接口限流

内置了两个限流注解:

  • @GuavaRateLimiter : guava 的限流实现
  • @SentinelRateLimiter : sentinel 的限流实现

在需要限流的接口上添加注解:

java
    @GetMapping(value = "/buy/ticket")
    @SentinelRateLimiter(100) 
    public String ticket() {
        return "Your got it!";
    }

数据脱敏

业务开发里常常有数据脱敏的场景,实现数据脱敏的方法很多,为了保证传输过程中数据的安全性,一般需要在接口返回层就完成脱敏。

组件提供了注解 @Sensitive 用于对敏感字段进行脱敏处理,使用:

java
public class Person implements Serializable {
    private String name;

    @Sensitive(type = SensitiveType.ADDRESS) 
    private String address;                
}

其中,内置了常用数据类型的脱敏,如 密码(PASSWORD)、地址(ADDRESS), 中文名(CHINESE_NAME), 身份证号(ID_CARD), 手机号(MOBILE), 邮箱地址(EMAIL) 当然,也支持自定制正则和 mask 字符,如:

java
public class Person implements Serializable {
    private String name;

    @Sensitive(type = SensitiveType.EMPTY, pattern = "(.{3})(.{6})(.{3})(.+)", group = {2, 4}, mask = "x") 
    private String address;                
}

返回数据长这样:

json
{
    "id": "1",
    "name": "Jacky",
    "address": "江苏省xxxxxx区安德xxxxxx", 
  }

接口全局响应

内部对controller接口响应以及异常做了统一封装,使用时在相应的controller类上添加注解 @EnableRespAdvice 用于开启advice功能:

java
@EnableRespAdvice
@RestController
@RequestMapping("/demo/api/v1")
@Tag(name = "测试api")
public class DemoApiController {
}

排除全局响应

在需要排除的接口方法上添加注解 @RespAdviceExclude 即可忽略该方法的返回结果

自定义成功和失败响应

支持对成功和失败响应的code 以及 message 内容进行定制,使用配置实现:

yaml
application:
    resp:
      success-code: 200   # 默认 0
      success-msg: 'ok'
      fail-code: 500 # 默认 9999

自定义异常

提供了一个注解 @ErrorAdvice 用于标记自定义的异常类,用法:

java
@ErrorAdvice(code = 10001, message = "自定义异常")
public class MyException extends RuntimeException {

    public MyException(String msg) {
        super(msg);
    }

    public MyException() {
    }
}

在service 或controller 中抛出该异常,则会显示注解的内容

配置项加密

出于安全考虑,数据库账户密码、其他一些敏感配置信息都应该加密后再加到配置文件中,集成了 jasypt 用于实现。

生成加密字符串

确定自己使用的加密密钥,然后可以调用提供的 JasyptUtil 来生成加密后的字符串

java
        String password = "happy-every-day";  // 加密密钥
        String plaintext = "mysadday";  // 要加密的明文

        String encryptedText = JasyptUtil.encrypt(password, plaintext);
        System.out.println("加密后: " + encryptedText);

设置配置项值和密钥

将加密后的字符串使用 ENC(加密密文) 填充到配置文件的对应位置,如:

yaml
redis:
  password: ENC(加密后的Redis密码)

加密密钥不可以直接放到配置文件里,应该通过环境变量或系统属性来设置:

shell
java -Djasypt.encryptor.password=your-secret-password -jar your-application.jar

方法调用日志记录

使用切面实现了任意方法调用的参数、返回值、耗时等的记录,无侵入方式实现,只需要添加注解即可:

java
  @GetMapping("/greeting/{name}")
  @MethodLogger(module = "MY")
  public Response<String> getName(@PathVariable String name) {
     return responseFactory.createSuccess("hello , ".concat(String.valueOf(name.charAt(0)).toUpperCase()).concat(name.substring(1)));
  }

module 用于标注该方法所属的模块 便于日志检索分析

时间字段格式化

采用 jackson 序列化数据时,默认对于 jdk8 的Local时间类型,不能很好的展示,现在可在配置文件中自定义返回的格式(扩展了 spring.jackson 配置项)

yaml
#  自定义 jackson 返回的时间字段的格式
application:
    jackson:
      local-date-format: YY年MM月dd日
      local-time-format: HH:mm:ss

swagger v3注解变化说明

功能维度Swagger 2 注解(已过时)Swagger 3 注解(OpenAPI 3)迁移备注
控制器/分组@Api(tags = "xxx")@Tag(name = "xxx", description = "xxx")可重复打标签;一个控制器支持多个 @Tag
接口方法@ApiOperation(value = "xxx")@Operation(summary = "xxx", description = "xxx")新加 operationIddeprecatedsecurity 等属性
路径参数/查询参数@ApiParam(value = "xxx", required = true)@Parameter(description = "xxx", required = true)包路径也换了:io.swagger.v3.oas.annotations.*
隐式参数(非 Spring 注解)@ApiImplicitParam/@ApiImplicitParams直接 @Parameter 放在 @Operation3.0 不再区分“隐式”
请求/响应体模型@ApiModel(description = "xxx") 类级别
@ApiModelProperty(notes = "xxx") 字段
@Schema(description = "xxx") 类+字段通用一个注解搞定,支持 examplerequiredModeaccessMode
响应码描述@ApiResponses({@ApiResponse(code = 200, message = "xxx")})@ApiResponse(responseCode = "200", description = "xxx")字段名从 code→responseCodemessage→description
忽略某接口Docketapis()/paths() 过滤同上,或直接在方法写 @Hidden更细粒度
安全/授权@ApiOperation(authorizations = {@Authorization(value = "jwt")})@Operation(security = {@SecurityRequirement(name = "jwt")})先通过 OpenAPI Bean 声明 SecurityScheme,再引用

好了,本章节就到这里,如果需要更多业务功能特性,可完善此文档添加.

Released under the MIT License.