• Springboot教程一使用合理的参数校验拦截判断请求参数是否规范化合理化参数校验


    目录

    前言

    SpringBoot自带的校验规则

    实现案例关键性代码

    校验规则

    业务上使用功能的校验规则仅仅针对特定业务场景

    工具类的校验代码如下

    还有一个是自定义实现的拦截校验放到下一篇里面讲解


    前言

    这一篇主要说的是,使用SpringBoot里面自带的一些参数校验插件,只要使用功能SpringBoot,基本是web或者微服务的功能,部署到服务器上,基本上都是做业务操作的,结案是业务操作,那就是有一定的,需要参数格式化校验以及规范化处理。

    主要参数校验主要有以下几个方法的。这些是一些基本的参数,如果要是使用其他的参数还是需要自定义实现类的。

    SpringBoot自带的校验规则

    @NotBlank: 判断字符串是否为 null 或者是空串(去掉首尾空格)。
    @NotEmpty: 判断字符串是否 null 或者是空串。
    @Length: 判断字符的长度(最大或者最小)
    @Min: 判断数值最小值
    @Max: 判断数值最大值
    @Email: 判断邮箱是否合法

    实现案例关键性代码

    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.validation.Valid;
    1. @RequestMapping(value = "/handleZeroRate", method = RequestMethod.GET)
    2. @ApiOperation(value = "90天内的定时任务")
    3. public ApiResponse handleZeroRate(@Valid String handleStr, BindingResult bindingResult) {
    4. ApiResponse response = ApiResponseBuilder.newSuccessResponse();
    5. try {
    6. if(bindingResult.hasErrors()){
    7. Map map = new HashMap(2);
    8. map.put("定时任务参数入参不合法:",handleStr);
    9. response.setData((JSONObject) JSONObject.toJSON(map));
    10. return response;
    11. }
    12. filterPushTimeTaskFacade.performTasks();
    13. Map map = new HashMap(2);
    14. map.put("运行结果完成", "定时任务成功完成");
    15. response.setData((JSONObject) JSONObject.toJSON(map));
    16. } catch (Exception ex) {
    17. return ApiResponseBuilder.newErrorResponse(ex);
    18. }
    19. return response;
    20. }

    校验规则

    主要是不需要判断是否是空了,一个简单地校验规则,复杂的话,需要自己实现一下了

     

    业务上使用功能的校验规则仅仅针对特定业务场景

    关键性代码块如下。此处是使用工具类来进行校验输入的日期格式化是否正常合法的。

    if (DateParseUtils.invalid(date, DateUtils.FORMAT_PATTERN_YYYY_MM_DD)) {
        ResponseBuilder.errorRes(response, WebCodeEnum.ERROR_DATE_PARAM);
        return;
    }
    1. @GetMapping("/target")
    2. public void target(String date, HttpServletResponse response) throws IOException {
    3. if (DateParseUtils.invalid(date, DateUtils.FORMAT_PATTERN_YYYY_MM_DD)) {
    4. ResponseBuilder.errorRes(response, WebCodeEnum.ERROR_DATE_PARAM);
    5. return;
    6. }
    7. List dataList = exportDataService.packageDataList(date);
    8. // 过滤00:00:00-07:00:00
    9. List resultList = dataList.stream().filter(data -> data.getOrder() != 1).collect(Collectors.toList());;
    10. try {
    11. response.setContentType("application/vnd.ms-excel");
    12. response.setCharacterEncoding("utf-8");
    13. String fileName = URLEncoder.encode("中台舆情生产观察指标-" + date, "UTF-8");
    14. response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    15. // 这里需要设置不关闭流
    16. EasyExcel.write(response.getOutputStream(), TimeTargetData.class).autoCloseStream(Boolean.FALSE).sheet(date + "指标数据").doWrite(resultList);
    17. } catch (Exception e) {
    18. ResponseBuilder.errorRes(response, WebCodeEnum.ERROR, e.getMessage());
    19. }
    20. }

    工具类的校验代码如下

    业务上经常使用的是工具类来替换这个校验规则,主要是针对日期或者字符串以及对象啥的进行一层层判断。其实并不太好维护,因为规则可能不断叠加的。这么多的ifelse要写到什么时候呢?

    1. @Slf4j
    2. public class DateParseUtils extends DateUtils {
    3. /**
    4. * 判断日期字符串格式是否符合格式化要求
    5. * @param dateStr 日期字符串
    6. * @param format 格式化方式
    7. * @return true-符合,false-不符合
    8. */
    9. public static boolean valid(String dateStr, String format) {
    10. if (StringUtils.isBlank(dateStr)) {
    11. return false;
    12. }
    13. try {
    14. return parseDate(dateStr, format) != null;
    15. } catch (Exception e) {
    16. log.error("错误的日期格式:{},格式化方式为:{}", dateStr, format);
    17. return false;
    18. }
    19. }
    20. /**
    21. * 判断日期字符串格式是否不符合格式化要求
    22. * @param dateStr 日期字符串
    23. * @param format 格式化方式
    24. * @return true-不符合,false-符合
    25. */
    26. public static boolean invalid(String dateStr, String format) {
    27. return !valid(dateStr, format);
    28. }
    29. /**
    30. * 按日期格式解析日期字符串
    31. * @param dateStr 日期字符串
    32. * @param format 日期格式
    33. * @return {@code LocalDate}
    34. */
    35. public static LocalDate parseDate(String dateStr, String format) {
    36. DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
    37. return LocalDate.parse(dateStr, formatter);
    38. }
    39. /**
    40. * 按日期时间格式解析日期字符串
    41. * @param dateTimeStr 日期时间字符串
    42. * @param format 日期格式
    43. * @return {@code Instant}
    44. */
    45. public static Instant parseDateTime(String dateTimeStr, String format) {
    46. DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
    47. return LocalDateTime.parse(dateTimeStr, formatter).atZone(ZoneId.systemDefault()).toInstant();
    48. }
    49. /**
    50. * 按日期格式解析日期字符串
    51. * @param dateStr 日期时间字符串
    52. * @param format 日期格式
    53. * @return {@code Date}
    54. */
    55. public static Date parseDateStr(String dateStr, String format) {
    56. return Date.from(parseDateTime(dateStr, format));
    57. }
    58. /**
    59. * 根据时间戳转换成日期格式
    60. * @param timestamp 时间戳
    61. * @return 日期
    62. */
    63. public static Date parseTimestamp(Long timestamp) {
    64. if (timestamp == null) {
    65. return null;
    66. }
    67. if (timestamp < 9999999999L) {
    68. return new Date(timestamp * 1000);
    69. }
    70. return new Date(timestamp);
    71. }
    72. /**
    73. * 按日期格式解析日期字符串
    74. * @param dateStr 日期字符串
    75. * @param timeStr 时间字符串
    76. * @param format 日期格式
    77. * @return {@code Date}
    78. */
    79. public static Date parseDateTimeStr(String dateStr, String timeStr, String format) {
    80. if (StringUtils.isBlank(dateStr)) {
    81. return null;
    82. }
    83. if (StringUtils.isBlank(timeStr.trim())) {
    84. timeStr = "00:00:00";
    85. }
    86. return Date.from(parseDateTime(dateStr.split(" ")[0] + StringUtils.SPACE + timeStr.trim(), format));
    87. }
    88. /**
    89. * 解析日期字符串
    90. * @param dateStr 日期字符串
    91. * @return {@code Date}
    92. */
    93. public static Date parseDateStr(String dateStr) {
    94. if (StringUtils.isBlank(dateStr)) {
    95. return null;
    96. }
    97. if (dateStr.length() == FORMAT_PATTERN_DEFAULT.length()) {
    98. return parseDateStr(dateStr, FORMAT_PATTERN_DEFAULT);
    99. } else if (dateStr.length() == FORMAT_PATTERN_YYYY_MM_DD.length()) {
    100. return parseDateStr(dateStr + " 00:00:00", FORMAT_PATTERN_DEFAULT);
    101. }
    102. return null;
    103. }
    104. /**
    105. * 解析日期时间字符串
    106. * @param dateStr 日期字符串
    107. * @param timeStr 时间字符串
    108. * @return {@code Date}
    109. */
    110. public static Date parseDateTimeStr(String dateStr, String timeStr) {
    111. if (StringUtils.isBlank(timeStr)) {
    112. return parseDateStr(dateStr);
    113. } else {
    114. return parseDateStr(dateStr + StringUtils.SPACE + timeStr);
    115. }
    116. }
    117. /**
    118. * 返回指定日期最大时间值
    119. * @param dateStr 指定日期
    120. * @return 指定日期最大时间值
    121. */
    122. public static LocalDateTime atEndOfDay(String dateStr) {
    123. return atEndOfDay(dateStr, FORMAT_PATTERN_YYYY_MM_DD);
    124. }
    125. /**
    126. * 返回指定日期最小时间值
    127. * @param dateStr 指定日期
    128. * @return 指定日期最小时间值
    129. */
    130. public static LocalDateTime atStartOfDay(String dateStr) {
    131. return atStartOfDay(dateStr, FORMAT_PATTERN_YYYY_MM_DD);
    132. }
    133. /**
    134. * 返回指定日期最大时间值
    135. * @param dateStr 指定日期
    136. * @param format 格式化类型
    137. * @return 指定日期最大时间值
    138. */
    139. public static LocalDateTime atEndOfDay(String dateStr, String format) {
    140. return parseDate(dateStr, format).atStartOfDay().with(LocalTime.MAX);
    141. }
    142. /**
    143. * 返回指定日期最小时间值
    144. * @param dateStr 指定日期
    145. * @param format 格式化类型
    146. * @return 指定日期最小时间值
    147. */
    148. public static LocalDateTime atStartOfDay(String dateStr, String format) {
    149. return parseDate(dateStr, format).atStartOfDay();
    150. }
    151. }

    还有一个是自定义实现的拦截校验放到下一篇里面讲解

  • 相关阅读:
    ruoyi系统启动
    Java多线程-线程的状态和线程常用方法
    C - Songs Compression
    pod 创建自定义库失败后解决方案
    大学物理·第7章恒定磁场
    HTTP协议详解:基本概念与工作流程
    【yolo算法道路井盖检测】
    计控实验(三)——最少拍控制器
    成功拿下阿里一面HashMap追魂二十三问
    使用Maxent模型预测适生区
  • 原文地址:https://blog.csdn.net/m0_59252007/article/details/125891510