# SpringBoot 学习
# 参数校验
# 简单校验@Valid
@Slf4j
@Api(value = "User Interfaces",tags = "User Interfaces")
@RestController
@RequestMapping("/user")
public class UserController {
@ApiOperation("Add User")
@ApiImplicitParam(name="userParam",type="body",dataTypeClass = UserParam.class,required = true)
@PostMapping("add")
public ResponseEntity<String> add(@Valid @RequestBody UserParam userParam, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
errors.forEach(p -> {
FieldError fieldError = (FieldError) p;
log.error("Invalid Parameter : object - {},field - {},errorMessage - {}", fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
});
return ResponseEntity.badRequest().body("invalid parameter");
}
return ResponseEntity.ok("success");
}
}
# 分组校验@Validated
@Slf4j
@Api(value = "User Interfaces",tags = "User Interfaces")
@RestController
@RequestMapping("/user")
public class UserController {
@ApiOperation("Add User")
@ApiImplicitParam(name="userParam",type="body",dataTypeClass = UserParam.class,required = true)
@PostMapping("add")
public ResponseEntity<UserParam> add(@Validated(AddValidationGroup.class) @RequestBody UserParam userParam){
return ResponseEntity.ok(userParam);
}
@ApiOperation("Edit User")
@ApiImplicitParam(name= "userParam",type="body",dataTypeClass = UserParam.class,required = true)
@PostMapping("edit")
public ResponseEntity<UserParam> edit(@Validated(EditValidationGroup.class) @RequestBody UserParam userParam){
return ResponseEntity.ok(userParam);
}
}
两者区别:
- @Validated:可以用在方法、方法参数、类型上。但是不能用在成员属性(字段)上
- @Valid:可以用在方法、方法参数、构造函数和成员属性(字段)上
# 常用校验
- JSR303/JSR-349 位于javax.validation.constraints下,规定一些校验规范,如@Null,@NotNul,@NotEmpty
- hibernate validation 新增了注解@Email, @Length,@Range
- spring validation 二次封装,自动校验
# 自定义校验规则
# 定义注解
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {TelephoneNumberValidator.class}) // 指定校验器
public @interface TelephoneNumber {
String message() default "Invalid telephone number";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
# 定义校验器
public class TelephoneNumberValidator implements ConstraintValidator<TelephoneNumber, String> {
private static final String REGEX_TEL = "0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|13[0-9]\\d{8}|15[1089]\\d{8}";
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
try {
return Pattern.matches(REGEX_TEL, s);
} catch (Exception e) {
return false;
}
}
}
# 使用
@Data
@Builder
@ApiModel(value = "User", subTypes = {AddressParam.class})
public class UserParam implements Serializable {
private static final long serialVersionUID = 1L;
@NotEmpty(message = "{user.msg.userId.notEmpty}", groups = {EditValidationGroup.class})
private String userId;
@TelephoneNumber(message = "invalid telephone number") // 这里
private String telephone;
}
原文链接:https://pdai.tech/md/spring/springboot/springboot-x-interface-param.html
# swagger文档的使用
swagger可以通过配置注解的方式自动为springboot项目生产接口文档,3.0版本支持导出json文件可以在ApiFox中加载使用。
支持在配置全局请求参数,全局响应参数和文档信息,是一种侵入式文档配置
# 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
# API配置
/**
* swagger config for open api.
*
* @author
*/
@Configuration
@EnableOpenApi
public class OpenApiConfig {
/**
* open api extension by knife4j.
*/
private final OpenApiExtensionResolver openApiExtensionResolver;
@Autowired
public OpenApiConfig(OpenApiExtensionResolver openApiExtensionResolver) {
this.openApiExtensionResolver = openApiExtensionResolver;
}
/**
* 配置Docket对象以便生成文档
* @return swagger config
*/
@Bean
public Docket openApi() {
String groupName = "Test Group";
return new Docket(DocumentationType.OAS_30) // 指定文档类型
.groupName(groupName) // 指定分组名称
.apiInfo(apiInfo())// 设置API文档基本信息
.select() // 可见性配置
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))// 只有使用了@ApiOperation注解的方法生成文档
.paths(PathSelectors.any())// 设置所有路径的配置
.build() //构建Docket对象
.globalRequestParameters(getGlobalRequestParameters()) //全局请求参数
.globalResponses(HttpMethod.GET, getGlobalResponse()) //全局响应参数
.extensions(openApiExtensionResolver.buildExtensions(groupName)) // 添加API扩展
.extensions(openApiExtensionResolver.buildSettingExtensions()); // 添加设置扩展
}
/**
* 获取响应码和状态描述
* @return global response code->description
*/
private List<Response> getGlobalResponse() {
return ResponseStatus.HTTP_STATUS_ALL.stream().map(
a -> new ResponseBuilder().code(a.getResponseCode()).description(a.getDescription()).build())
.collect(Collectors.toList());
}
/**
* 全局请求参数
* @return global request parameters
*/
private List<RequestParameter> getGlobalRequestParameters() {
List<RequestParameter> parameters = new ArrayList<>();
parameters.add(new RequestParameterBuilder()
.name("AppKey")
.description("应用 Key")
.required(false)
.in(ParameterType.QUERY)
.query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
.required(false)
.build());
return parameters;
}
/** 设置API文档信息
* @return api info
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger/OpenApi")
.description("api测试")
.contact(new Contact("hui", "http://huyadish.com", ""))
.termsOfServiceUrl("http://xxxxxx.com/")
.version("1.0")
.build();
}
}
# YML配置
server:
port: 8080
knife4j:
enable: true
documents:
- group: Test Group # 文档分类名称
name: My Documents #文档名称
locations: classpath:wiki/*
setting:
# default lang
language: en-US
# footer
enableFooter: false
enableFooterCustom: true
footerCustomContent: MIT | Gaohui
# header
enableHomeCustom: true
homeCustomLocation: classpath:wiki/README.md
# models
enableSwaggerModels: true
swaggerModelName: My Models
# API使用
@Api(value = "用户接口", tags = "用户接口")
@RestController
@RequestMapping("/user")
public class UserController {
/**
* http://localhost:8080/user/add .
*
* @param userParam user param
* @return user
*/
@ApiOperation("添加用户")
@ApiImplicitParam(name = "userParam", type = "body", dataTypeClass = UserParam.class, required = true)
@PostMapping("add")
public ResponseEntity<String> add(@RequestBody UserParam userParam) {
return ResponseEntity.ok("success");
}
/**
* http://localhost:8080/user/list .
*
* @return user list
*/
@ApiOperation("查询用户列表")
@GetMapping("list")
public ResponseEntity<List<UserVo>> list() {
List<UserVo> userVoList = Collections.singletonList(UserVo.builder().name("hui").age(26).address(
AddressVo.builder().city("tianjin").zipcode("123465").build()
).build());
return ResponseEntity.ok(userVoList);
}
}
原文链接 https://www.pdai.tech/md/spring/springboot/springboot-x-interface-doc.html
# Smart-Doc文档
非侵入式,也是繁重的代码