09| Validated参数校验& 参数映射&时间格式化 & POST和GET

2024-07-30 · · 原创 · · 本文共 768个字,预计阅读需要 3分钟。

@Validated参数校验

  1. 导入依赖,如果SpringBoot版本的小于2.3.x,不需要导入,否则需要手动, 项目nal-common
  1. <!--如果spring-boot版本大于2.3.x,则需要手动引入依赖-->
  2. <dependency>
  3. <groupId>org.hibernate</groupId>
  4. <artifactId>hibernate-validator</artifactId>
  5. <version>6.0.1.Final</version>
  6. </dependency>

@Validated注解和@Valid注解区别

  1. import org.springframework.validation.annotation.Validated;
  2. import javax.validation.Valid;

@Valid:没有分组的功能。可以用在方法、构造函数、方法参数和成员属性(字段)上。可以提供嵌套校验的功能

@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上。没有嵌套校验的功能

定义全局的异常处理

CustomExceptionHandler中增加异常处理器,项目nal-common

  1. /**
  2. * 忽略参数异常处理器
  3. *
  4. * @param e 忽略参数异常
  5. */
  6. //@ResponseStatus(HttpStatus.BAD_REQUEST)
  7. @ExceptionHandler(MissingServletRequestParameterException.class)
  8. @ResponseBody
  9. public JsonData parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
  10. log.error("参数异常", e);
  11. return JsonData.buildError("请求参数[" + e.getParameterName() + "]不能为空");
  12. }
  13. /**
  14. * 缺少请求体异常处理器
  15. *
  16. * @param e 缺少请求体异常
  17. */
  18. //@ResponseStatus(HttpStatus.BAD_REQUEST)
  19. @ExceptionHandler(HttpMessageNotReadableException.class)
  20. @ResponseBody
  21. public JsonData parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
  22. log.error("缺少请求体异常", e);
  23. return JsonData.buildError("参数体不能为空");
  24. }
  25. /**
  26. * 参数效验异常处理器
  27. *
  28. * @param e 参数验证异常
  29. */
  30. //@ResponseStatus(HttpStatus.BAD_REQUEST)
  31. @ExceptionHandler(MethodArgumentNotValidException.class)
  32. @ResponseBody
  33. public JsonData parameterExceptionHandler(MethodArgumentNotValidException e) {
  34. log.error("参数效验异常", e);
  35. BindingResult bindingResult = e.getBindingResult();
  36. StringBuilder sb = new StringBuilder("校验失败: ");
  37. for (FieldError fieldError : bindingResult.getFieldErrors()) {
  38. // sb.append(fieldError.getDefaultMessage()).append(", ");
  39. sb.append("[").append(fieldError.getField()).append("]").append(fieldError.getDefaultMessage()).append(", ");
  40. }
  41. return JsonData.buildError(sb.toString());
  42. }
  43. /**
  44. * 自定义校验
  45. *
  46. * @param e 参数验证异常
  47. */
  48. @ExceptionHandler({ConstraintViolationException.class})
  49. @ResponseBody
  50. public JsonData handleConstraintViolationException(ConstraintViolationException e) {
  51. log.error("自定义校验异常", e);
  52. return JsonData.buildError(e.getMessage());
  53. }

自定义方法校验

自定义校验注解: cn.nla.common.annotation.EncryptId

  1. /**
  2. * 自定义加密校验
  3. */
  4. @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  5. @Retention(RUNTIME)
  6. @Documented
  7. @Constraint(validatedBy = {EncryptIdValidator.class})
  8. public @interface EncryptId {
  9. // 默认错误消息
  10. String message() default "加密id格式错误";
  11. // 分组
  12. Class<?>[] groups() default {};
  13. // 负载
  14. Class<? extends Payload>[] payload() default {};
  15. }

自定义校验逻辑:cn.nla.common.config.EncryptIdValidator

  1. import cn.nla.common.annotation.EncryptId;
  2. import javax.validation.ConstraintValidator;
  3. import javax.validation.ConstraintValidatorContext;
  4. import java.util.regex.Matcher;
  5. import java.util.regex.Pattern;
  6. /**
  7. * 自定义加密校验的方法
  8. */
  9. public class EncryptIdValidator implements ConstraintValidator<EncryptId, String> {
  10. // 字符串的长度: 32~256,以字母a到f或数字0到9开头。
  11. private static final Pattern PATTERN = Pattern.compile("^[a-f\\d]{32,256}$");
  12. @Override
  13. public boolean isValid(String value, ConstraintValidatorContext context) {
  14. // 不为null才进行校验
  15. if (value != null) {
  16. Matcher matcher = PATTERN.matcher(value);
  17. return matcher.find();
  18. }
  19. return true;
  20. }
  21. }

创建分组的接口

  1. package cn.nla.user.goup;
  2. /**
  3. * 保存
  4. */
  5. public interface Save {
  6. }
  7. /**
  8. * 更新
  9. */
  10. public interface Update {
  11. }

请求参数校验配置

  1. import cn.nla.common.annotation.EncryptId;
  2. import cn.nla.user.goup.Save;
  3. import cn.nla.user.goup.Update;
  4. import lombok.Data;
  5. import org.hibernate.validator.constraints.Length;
  6. import javax.validation.Valid;
  7. import javax.validation.constraints.*;
  8. import java.io.Serializable;
  9. import java.util.List;
  10. @Data
  11. public class StudentBean implements Serializable {
  12. @NotBlank(message = "用户名不能为空")
  13. private String name;
  14. @NotNull(groups = {Save.class, Update.class})
  15. @Length(min = 6, max = 20, groups = {Save.class, Update.class})
  16. private String account;
  17. @Min(value = 18, message = "年龄不能小于18岁")
  18. @NotNull(message = "年龄不能为空")
  19. private Integer age;
  20. @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 = "手机号格式错误")
  21. private String phoneNum;
  22. @Email(message = "邮箱格式错误")
  23. private String email;
  24. @Valid //嵌套只能使用Valid
  25. @NotNull(message = "任课老师不能为空")
  26. @Size(min = 1, message = "至少有一个老师")
  27. private List<TeacherBean> teacherBeans;
  28. @EncryptId(message = "密码格式错误")
  29. private String password;
  30. }

子对象TeacherBean

  1. import lombok.Data;
  2. import javax.validation.constraints.Min;
  3. import javax.validation.constraints.NotEmpty;
  4. @Data
  5. public class TeacherBean {
  6. @NotEmpty(message = "老师姓名不能为空")
  7. private String teacherName;
  8. @Min(value = 1, message = "学科类型从1开始计算")
  9. private int type;
  10. }

控制器使用

Post请求

  1. @PostMapping("query")
  2. public String query(@Validated @RequestBody StudentBean params) {
  3. log.info("请求参数:{}", params);
  4. return "成功";
  5. }

Get请求时,也是封装为对象进行校验

jackson注解

请求参数与SpringBoot接收参数映射

使用注解@JsonProperty

  1. @JsonProperty("product_id") //外部请求参数 &接收参数
  2. private long productId; // springboot内部接收参数

时间格式化JsonFormat

  1. @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
  2. private LocalDateTime updateTime;

@RestController处理GET&POST请求

GET - @RequestParam

  1. @GetMapping("query")
  2. public Object query(@RequestParam(value = "params",required = false,defaultValue = "参数") {}
  3. // get请求方式: /query?parmas=请求参数, 该请求参数是非必传参数,默认参数是:参数

GET - @PathVariable

没有required或defaultValue属性可以通过方法的逻辑来处理缺失的路径变量

  1. @GetMapping("query/{parmas}")
  2. public Object query(@PathVariable("parmas") String params) {}
  3. // get请求方式: /query/请求参数

GET - @ModelAttribute

ModelAttribute主要用于将请求参数(包括查询字符串参数、表单数据、路径变量等)绑定到Java对象上,并将这些对象添加到模型中,以便在视图渲染时使用。

  1. @GetMapping("query")
  2. public Object query(@ModelAttribute StudentBean bean) {}

POST- Form请求@RequestParam

表单提交

  1. @PostMapping("query")
  2. public Object query(@RequestParam("params") {}

POST-JSON请求

  1. @PostMapping("query")
  2. public Object query(@RequestBody StudentBean bean) {}

图片上传

  1. @PostMapping(value = "/uploadFile", name = "上传文件")
  2. public String uploadImage(MultipartFile file){}

请求头@RequestHeader

  1. @Post/GetMapping("query")
  2. public Object query(@RequestHeader("token") String token) {}
  3. // 此时如何请求头中没有token,会报错,不推荐使用
  1. @PostMapping("query")
  2. public Object query(@RequestHeader Map<String, String> headers){}
  3. // 推荐使用Map来接收请求头数据