项目
博客
文档
归档
资源链接
关于我
项目
博客
文档
归档
资源链接
关于我
09| Validated参数校验& 参数映射&时间格式化 & POST和GET
2024-07-30
·
·
原创
·
·
本文共 768个字,预计阅读需要 3分钟。
### @Validated参数校验 1. 导入依赖,如果SpringBoot版本的小于2.3.x,不需要导入,否则需要手动, 项目`nal-common` ```xml
org.hibernate
hibernate-validator
6.0.1.Final
``` #### @Validated注解和@Valid注解区别 ```java import org.springframework.validation.annotation.Validated; import javax.validation.Valid; ``` - @Validated是spring旗下的注解,@Valid注解时javax包下的注解,是jdk给提供的。 - @Validated:是spring提供的对@Valid的封装,常见用在方法上进行校验,**@Validated要比@Valid更加强大,@Validated在@Valid之上提供了分组功能和验证排序功能** @Valid:没有分组的功能。可以用在方法、构造函数、方法参数和成员属性(字段)上。**可以提供嵌套校验的功能** @Validated:提供了一个`分组功能`,可以在入参验证时,根据不同的分组采用不同的验证机制。可以用在类型、方法和方法参数上。但是`不能用在成员属性(字段`)上。**没有嵌套校验的功能** #### 定义全局的异常处理 CustomExceptionHandler中增加异常处理器,项目`nal-common` ```java /** * 忽略参数异常处理器 * * @param e 忽略参数异常 */ //@ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MissingServletRequestParameterException.class) @ResponseBody public JsonData parameterMissingExceptionHandler(MissingServletRequestParameterException e) { log.error("参数异常", e); return JsonData.buildError("请求参数[" + e.getParameterName() + "]不能为空"); } /** * 缺少请求体异常处理器 * * @param e 缺少请求体异常 */ //@ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseBody public JsonData parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) { log.error("缺少请求体异常", e); return JsonData.buildError("参数体不能为空"); } /** * 参数效验异常处理器 * * @param e 参数验证异常 */ //@ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public JsonData parameterExceptionHandler(MethodArgumentNotValidException e) { log.error("参数效验异常", e); BindingResult bindingResult = e.getBindingResult(); StringBuilder sb = new StringBuilder("校验失败: "); for (FieldError fieldError : bindingResult.getFieldErrors()) { // sb.append(fieldError.getDefaultMessage()).append(", "); sb.append("[").append(fieldError.getField()).append("]").append(fieldError.getDefaultMessage()).append(", "); } return JsonData.buildError(sb.toString()); } /** * 自定义校验 * * @param e 参数验证异常 */ @ExceptionHandler({ConstraintViolationException.class}) @ResponseBody public JsonData handleConstraintViolationException(ConstraintViolationException e) { log.error("自定义校验异常", e); return JsonData.buildError(e.getMessage()); } ``` #### 自定义方法校验 自定义校验注解: `cn.nla.common.annotation.EncryptId` ```java /** * 自定义加密校验 */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {EncryptIdValidator.class}) public @interface EncryptId { // 默认错误消息 String message() default "加密id格式错误"; // 分组 Class>[] groups() default {}; // 负载 Class extends Payload>[] payload() default {}; } ``` 自定义校验逻辑:`cn.nla.common.config.EncryptIdValidator` ```java import cn.nla.common.annotation.EncryptId; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 自定义加密校验的方法 */ public class EncryptIdValidator implements ConstraintValidator
{ // 字符串的长度: 32~256,以字母a到f或数字0到9开头。 private static final Pattern PATTERN = Pattern.compile("^[a-f\\d]{32,256}$"); @Override public boolean isValid(String value, ConstraintValidatorContext context) { // 不为null才进行校验 if (value != null) { Matcher matcher = PATTERN.matcher(value); return matcher.find(); } return true; } } ``` #### 创建分组的接口 ```java package cn.nla.user.goup; /** * 保存 */ public interface Save { } /** * 更新 */ public interface Update { } ``` #### 请求参数校验配置 ```java import cn.nla.common.annotation.EncryptId; import cn.nla.user.goup.Save; import cn.nla.user.goup.Update; import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.Valid; import javax.validation.constraints.*; import java.io.Serializable; import java.util.List; @Data public class StudentBean implements Serializable { @NotBlank(message = "用户名不能为空") private String name; @NotNull(groups = {Save.class, Update.class}) @Length(min = 6, max = 20, groups = {Save.class, Update.class}) private String account; @Min(value = 18, message = "年龄不能小于18岁") @NotNull(message = "年龄不能为空") private Integer age; @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误") private String phoneNum; @Email(message = "邮箱格式错误") private String email; @Valid //嵌套只能使用Valid @NotNull(message = "任课老师不能为空") @Size(min = 1, message = "至少有一个老师") private List
teacherBeans; @EncryptId(message = "密码格式错误") private String password; } ``` 子对象TeacherBean ```java import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; @Data public class TeacherBean { @NotEmpty(message = "老师姓名不能为空") private String teacherName; @Min(value = 1, message = "学科类型从1开始计算") private int type; } ``` #### 控制器使用 Post请求 ```java @PostMapping("query") public String query(@Validated @RequestBody StudentBean params) { log.info("请求参数:{}", params); return "成功"; } ``` Get请求时,也是封装为对象进行校验 **jackson注解**: ### 请求参数与SpringBoot接收参数映射 使用注解@JsonProperty ```java @JsonProperty("product_id") //外部请求参数 &接收参数 private long productId; // springboot内部接收参数 ``` ### 时间格式化JsonFormat ```java @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; ``` ### @RestController处理GET&POST请求 #### GET - @RequestParam ```java @GetMapping("query") public Object query(@RequestParam(value = "params",required = false,defaultValue = "参数") {} // get请求方式: /query?parmas=请求参数, 该请求参数是非必传参数,默认参数是:参数 ``` #### GET - @PathVariable 没有required或defaultValue属性可以通过方法的逻辑来处理缺失的路径变量 ```java @GetMapping("query/{parmas}") public Object query(@PathVariable("parmas") String params) {} // get请求方式: /query/请求参数 ``` #### GET - @ModelAttribute ModelAttribute主要用于将请求参数(包括查询字符串参数、表单数据、路径变量等)绑定到Java对象上,并将这些对象添加到模型中,以便在视图渲染时使用。 ```java @GetMapping("query") public Object query(@ModelAttribute StudentBean bean) {} ``` #### POST- Form请求@RequestParam 表单提交 ```java @PostMapping("query") public Object query(@RequestParam("params") {} ``` #### POST-JSON请求 ```java @PostMapping("query") public Object query(@RequestBody StudentBean bean) {} ``` #### 图片上传 ```java @PostMapping(value = "/uploadFile", name = "上传文件") public String uploadImage(MultipartFile file){} ``` #### 请求头@RequestHeader ```java @Post/GetMapping("query") public Object query(@RequestHeader("token") String token) {} // 此时如何请求头中没有token,会报错,不推荐使用 ``` ```java @PostMapping("query") public Object query(@RequestHeader Map
headers){} // 推荐使用Map来接收请求头数据 ```