广告
返回顶部
首页 > 资讯 > 精选 >Java中怎么实现接口数据校验
  • 404
分享到

Java中怎么实现接口数据校验

2023-06-15 21:06:12 404人浏览 独家记忆
摘要

今天就跟大家聊聊有关Java中怎么实现接口数据校验,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Controller接口层数据绑定校验实际上在Java开发中目前普通使用的Bean数据

今天就跟大家聊聊有关Java中怎么实现接口数据校验,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

Controller接口层数据绑定校验

实际上在Java开发中目前普通使用的Bean数据校验工具是"hibernate-validator",它是一个hibernete独立的jar包,所以使用这个jar包并不需要一定要集成Hibernete框架。该jar包主要实现并扩展了javax.validation(是一个基于jsR-303标准开发出来的Bean校验规范)接口。

由于Spring Boot在内部默认集成了"hibernate-validator",所以使用spring  Boot构建的Java工程可以直接使用相关注解来实现Bean的数据校验。例如我们最常编写的Controller层接口参数对象,可以在定义Bean类时直接编写这样的代码:

@Data public class CreateOrderDTO {      @NotNull(message = "订单号不能为空")     private String orderId;     @NotNull(message = "订单金额不能为空")     @Min(value = 1, message = "订单金额不能小于0")     private Integer amount;     @Pattern(regexp = "^1[3|4|5|7|8][0-9]{9}$", message = "用户手机号不合法")     private String mobileNo;     private String orderType;     private String status; }

如上所示代码,我们可以使用@NotNull注解来约束该字段必须不能为空,也可以使用@Min注解来约束字段的最小取值,或者还可以通过@Pattern注解来使用正则表达式来约束字段的格式(如手机号格式)等等。

以上这些注解都是“hibernate-validator”依赖包默认提供的,更多常用的注解还有很多,例如:

Java中怎么实现接口数据校验

利用这些约束注解,我们就可以很轻松的搞定接口数据校验,而不需要在业务逻辑中编写大量的if-else来进行数据合法性校验。而定义好Bean参数对象并使用相关注解实现参数值约束后,在Controller层接口定义中只需要使用@Validated注解就可以实现在接收参数后自动进行数据绑定校验了,具体代码如下:

@PostMapping("/createOrder") public CreateOrderBO validationTest(@Validated CreateOrderDTO createOrderDTO) {     return orderServiceImpl.createOrder(createOrderDTO); }

如上所示,在Controller层中通过Spring提供的@Validated注解可以自动实现数据Bean的绑定校验,如果数据异常则会统一抛出校验异常!

约束性注解扩展

在“hibernate-validator”依赖jar包中,虽然提供了很多很方便的约束注解,但是也有不满足某些实际需要的情况,例如我们想针对参数中的某个值约定其值的枚举范围,如orderType订单类型只允许传“pay”、“refund”两种值,那么现有的约束注解可能就没有特别适用的了。此外,如果对这样的枚举值,我们还想在约束定义中直接匹配代码中的枚举定义,以更好地统一接口参数与业务逻辑的枚举定义。那么这种情况下,我们还可以自己扩展定义相应地约束注解逻辑。

接下来我们定义新的约束注解@EnumValue,来实现上面我们所说的效果,具体代码如下:

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {EnumValueValidator.class}) public @interface EnumValue {      //默认错误消息     String message() default "必须为指定值";      //支持string数组验证     String[] strValues() default {};      //支持int数组验证     int[] intValues() default {};      //支持枚举列表验证     Class<?>[] enumValues() default {};      //分组     Class<?>[] groups() default {};      //负载     Class<? extends Payload>[] payload() default {};      //指定多个时使用     @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})     @Retention(RUNTIME)     @Documented     @interface List {         EnumValue[] value();     }           class EnumValueValidator implements ConstraintValidator<EnumValue, Object> {          //字符串类型数组         private String[] strValues;         //int类型数组         private int[] intValues;         //枚举类         private Class<?>[] enumValues;                   @Override         public void initialize(EnumValue constraintAnnotation) {             strValues = constraintAnnotation.strValues();             intValues = constraintAnnotation.intValues();             enumValues = constraintAnnotation.enumValues();         }                   @SneakyThrows         @Override         public boolean isValid(Object value, ConstraintValidatorContext context) {             //针对字符串数组的校验匹配             if (strValues != null && strValues.length > 0) {                 if (value instanceof String) {                     for (String s : strValues) {//判断值类型是否为Integer类型                         if (s.equals(value)) {                             return true;                         }                     }                 }             }             //针对整型数组的校验匹配             if (intValues != null && intValues.length > 0) {                 if (value instanceof Integer) {//判断值类型是否为Integer类型                     for (Integer s : intValues) {                         if (s == value) {                             return true;                         }                     }                 }             }             //针对枚举类型的校验匹配             if (enumValues != null && enumValues.length > 0) {                 for (Class<?> cl : enumValues) {                     if (cl.isEnum()) {                         //枚举类验证                         Object[] objs = cl.getEnumConstants();                         //这里需要注意,定义枚举时,枚举值名称统一用value表示                         Method method = cl.getMethod("getValue");                         for (Object obj : objs) {                             Object code = method.invoke(obj, null);                             if (value.equals(code.toString())) {                                 return true;                             }                         }                     }                 }             }             return false;         }     } }

如上所示的@EnumValue约束注解,是一个非常实用的扩展,通过该注解我们可以实现对参数取值范围(不是大小范围)的约束,它支持对int、string以及enum三种数据类型的约束,具体使用方式如下:

 @EnumValue(strValues = {"pay", "refund"}, message = "订单类型错误") private String orderType;  @EnumValue(enumValues = Status.class, message = "状态值不在指定范围") private String status;

如上所示代码,该扩展注解既可以使用strValues或intValues属性来编程列举取值范围,也可以直接通过enumValues来绑定枚举定义。但是需要注意,处于通用考虑,具体枚举定义的属性的名称要统一匹配为value、desc,例如Status枚举定义如下:

public enum Status {     PROCESSING(1, "处理中"),     SUCCESS(2, "订单已完成");     Integer value;     String desc;      Status(Integer value, String desc) {         this.value = value;         this.desc = desc;     }      public Integer getValue() {         return value;     }      public String getDesc() {         return desc;     } }

通过注解扩展,就能实现更多方便的约束性注解!

更加灵活的数据校验工具类封装

除了上面直接在Controller层使用@Validated进行绑定数据校验外,在有些情况,例如你的参数对象中的某个字段是一个复合对象,或者业务层的某个方法所定义的入参对象也需要进行数据合法性校验,那么这种情况下如何实现像Controller层一样的校验效果呢?

需要说明在这种情况下@Validated已经无法直接使用了,因为@Validated注解发挥作用主要是Spring  mvc在接收参数的过程中实现了自动数据绑定校验,而在普通的业务方法或者复合参数对象中是没有办法直接绑定校验的。这种情况下,我们可以通过定义ValidateUtils工具类来实现一样的校验效果,具体代码如下:

public class ValidatorUtils {      private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();           public static void validate(Object obj, Class<?>... groups) {         Set<ConstraintViolation<Object>> resultSet = validator.validate(obj, groups);         if (resultSet.size() > 0) {             //如果存在错误结果,则将其解析并进行拼凑后异常抛出             List<String> errORMessageList = resultSet.stream().map(o -> o.getMessage()).collect(Collectors.toList());             StringBuilder errorMessage = new StringBuilder();             errorMessageList.stream().forEach(o -> errorMessage.append(o + ";"));             throw new IllegalArgumentException(errorMessage.toString());         }     } }

如上所示,我们定义了一个基于"javax.validation"接口的工具类实现,这样就可以在非@Validated直接绑定校验的场景中通过校验工具类来实现对Bean对象约束注解的校验处理,具体使用代码如下:

public boolean orderCheck(OrderCheckBO orderCheckBO) {     //对参数对象进行数据校验     ValidatorUtils.validate(orderCheckBO);     return true; }

而方法入参对象则还是可以继续使用前面我们介绍的约束性注解进行约定,例如上述方法的入参对象定义如下:

@Data @Builder public class OrderCheckBO {      @NotNull(message = "订单号不能为空")     private String orderId;     @Min(value = 1, message = "订单金额不能小于0")     private Integer orderAmount;     @NotNull(message = "创建人不能为空")     private String operator;     @NotNull(message = "操作时间不能为空")     private String operatorTime; }

这样在编程体验上就可以整体上保持一致!

数据合法性校验结果异常统一处理

通过前面我们所讲的各种约束注解,我们实现了对Controller层接口以及业务方法参数对象的统一数据校验。而为了保持校验异常处理的统一处理和错误报文统一输出,我们还可以定义通用的异常处理机制,来保证各类数据校验错误都能以统一错误格式反馈给调用方。具体代码如下:

@Slf4j @ControllerAdvice public class GlobalExceptionHandler {          @ExceptionHandler(BindException.class)     @ResponseBody     public ResponseResult<?> processValidException(httpservletResponse response, BindException e) {         response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());         //获取校验错误结果信息,并将信息组装         List<String> errorStringList = e.getBindingResult().getAllErrors()                 .stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList());         String errorMessage = String.join("; ", errorStringList);         response.setContentType("application/JSON;charset=UTF-8");         log.error(e.toString() + "_" + e.getMessage(), e);         return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9998.getCode(),                 errorMessage);     }           @ExceptionHandler(IllegalArgumentException.class)     @ResponseBody     public ResponseResult<?> processValidException(HttpServletResponse response, IllegalArgumentException e) {         response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());         String errorMessage = String.join("; ", e.getMessage());         response.setContentType("application/json;charset=UTF-8");         log.error(e.toString() + "_" + e.getMessage(), e);         return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9998.getCode(),                 errorMessage);     }      ... }

如上所示,我们定义了针对前面两种数据校验方式的统一异常处理机制,这样数据校验的错误信息就能通过统一的报文格式反馈给调用端,从而实现接口数据报文的统一返回!

其中通用的接口参数对象ResponseResult的代码定义如下:

@Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonPropertyOrder({"code", "message", "data"}) public class ResponseResult<T> implements Serializable {      private static final long serialVersionUID = 1L;           @JsonInclude(JsonInclude.Include.NON_NULL)     private T data;          private Integer code;          private String message;           public static <T> ResponseResult<T> OK(T data) {         return packageObject(data, GlobalCodeEnum.GL_SUCC_0);     }           public static <T> ResponseResult<T> systemException(Integer code, String message) {         return packageObject(null, code, message);     } }

当然,这样的统一报文格式也不仅仅只处理异常返回,正常的数据报文格式也可以通过该对象来进行统一封装!

看完上述内容,你们对Java中怎么实现接口数据校验有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

--结束END--

本文标题: Java中怎么实现接口数据校验

本文链接: https://www.lsjlt.com/news/281641.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中怎么实现接口数据校验
    今天就跟大家聊聊有关Java中怎么实现接口数据校验,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Controller接口层数据绑定校验实际上在Java开发中目前普通使用的Bean数据...
    99+
    2023-06-15
  • springboot接口参数校验JSR303的实现
    目录一、在controller接口处理校验异常二、统一异常处理三、错误码枚举类四、自定义参数校验注解在 javax.validation.constraints包中定义了非常多的校验...
    99+
    2022-11-13
    springboot接口参数校验JSR303 springboot JSR303
  • 浅谈Java 三种方式实现接口校验
    本文介绍了Java 三种方式实现接口校验,主要包括AOP,MVC拦截器,分享给大家,具体如下:方法一:AOP代码如下定义一个权限注解package com.thinkgem.jeesite.common.annotation; impor...
    99+
    2023-05-30
    java 接口 校验
  • SpringBoot接口怎么对参数进行校验
    今天小编给大家分享一下SpringBoot接口怎么对参数进行校验的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。什么是不优雅的...
    99+
    2023-07-02
  • Spring Validation怎么实现数据校验
    这篇文章主要讲解了“Spring Validation怎么实现数据校验”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring Validation怎么实现数据校验”吧...
    99+
    2023-07-05
  • C++ Protobuf实现接口参数自动校验详解
    目录1、背景2、方案简介3、 使用4、测试1、背景 用C++做业务发开的同学是否还在不厌其烦的编写大量if-else模块来做接口参数校验呢?当接口字段数量多大几十个,这样的参数校验代...
    99+
    2023-05-16
    C++ Protobuf实现接口参数校验 C++ Protobuf接口参数校验 C++ Protobuf参数校验 C++ Protobuf
  • java开发之基于Validator接口的SpringMVC数据校验方式
    目录1.定义实体类Account2.自定义验证器 AccountValidator,实现 Validator 接口3.控制器4. springmvc.xml 配置验证器5.jsp文件...
    99+
    2022-11-12
  • SpringBoot实现接口的各种参数校验的示例
    目录1.添加依赖2.接口参数校验2.1 requestBody参数校验2.2 requestParam/PathVariable参数校验3.统一异常处理4.进阶使用4.1 分组校验4...
    99+
    2022-11-13
  • 如何通过ECharts和php接口实现统计图的数据验证和校验
    如何通过ECharts和PHP接口实现统计图的数据验证和校验随着数据可视化的需求增加,ECharts成为了一个非常流行的数据可视化工具。而PHP作为一种常见的后端脚本语言,也广泛应用于Web开发中。本文将介绍如何通过ECharts和PHP接...
    99+
    2023-12-18
    echarts 数据校验 PHP接口
  • java签名校验功能怎么实现
    要实现Java签名校验功能,你可以按照以下步骤进行: 获取签名证书:首先,你需要获取要校验的文件的签名证书。可以使用Java的Ke...
    99+
    2023-10-26
    java
  • 怎么实现java开发SpringBoot参数校验过程
    这篇文章主要讲解了“怎么实现java开发SpringBoot参数校验过程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现java开发SpringBoot参数校验过程”吧!为什么需要参数...
    99+
    2023-06-25
  • 使用SpringMVC怎么实现对数据进行校验
    使用SpringMVC怎么实现对数据进行校验?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、导入jar包若要实现数据校验功能,需要导入必要的jar包,主要包括以下几个:c...
    99+
    2023-05-31
    springmvc
  • Java利用自定义注解实现数据校验
    目录JSR303介绍引入依赖常用注解开启校验数据校验测试自定义的封装错误信息统一异常处理分组校验创建分组校验接口添加校验注解开启分组校验自定义校验编写自定义的校验注解编写自定义的校验...
    99+
    2022-11-13
  • Java怎么实现双重校验锁单例
    这篇文章主要介绍了Java怎么实现双重校验锁单例的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么实现双重校验锁单例文章都会有所收获,下面我们一起来看看吧。代码实现Java代码实现如下://双重校验锁单...
    99+
    2023-06-28
  • springboot中validator数据校验功能的实现
    普通校验 导入依赖: 默认的报错:没有提示具体的属性 设置自己的错误信息提示:创建 ValidationMessages.properties 内容如下: user.id....
    99+
    2022-11-12
  • Java中的接口怎么实现
    这篇文章主要介绍“Java中的接口怎么实现”,在日常操作中,相信很多人在Java中的接口怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的接口怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-03
  • javascript怎么实现进行客户端数据的校验
    这篇文章主要讲解了“javascript怎么实现进行客户端数据的校验”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript怎么实现进行客户端数据的校验”吧!脚本代码:<scrip...
    99+
    2023-06-03
  • Spring Boot怎么实现请求参数校验
    这篇文章主要介绍了Spring Boot怎么实现请求参数校验的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring Boot怎么实现请求参数校验文章都会有所收获,下面我们一...
    99+
    2022-10-19
  • java中List接口怎么实现类
    这篇文章主要讲解了“java中List接口怎么实现类”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java中List接口怎么实现类”吧!List接口介绍—ArrayList有序、可重复线程不...
    99+
    2023-06-22
  • js前端表单数据处理和校验怎么实现
    这篇文章主要介绍了js前端表单数据处理和校验怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇js前端表单数据处理和校验怎么实现文章都会有所收获,下面我们一起来看看吧。1.数据处理当表单在视图所展示的数据并...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作