iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么通过自定义spring invalidator注解校验数据合法性
  • 648
分享到

怎么通过自定义spring invalidator注解校验数据合法性

2023-07-02 15:07:04 648人浏览 安东尼
摘要

今天小编给大家分享一下怎么通过自定义spring invalidator注解校验数据合法性的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面

今天小编给大家分享一下怎么通过自定义spring invalidator注解校验数据合法性的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

自定义spring invalidator注解校验数据合法性

项目中经常会对用户输入的数据,或者外部导入到系统的数据做合法性检查。在Spring Boot框架微服务中可以使用invalidator注解对数据做合法性,安全性校验。

下面给一个样例说明如何自定义注解实现校验逻辑。

1、定义校验属性字符串长度的注解

package com.elon.SpringBootdemo.manager.invalidator;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import javax.validation.Constraint;import javax.validation.Payload;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = FieldLengthInvalidatorImpl.class)@Documentedpublic @interface FieldLengthInvalidator {    // 字段支持的最大长度(字符数)    int maxLength() default 50;    // 校验失败后返回的错误信息    String message() default "";    // 分组    Class<?>[] groups() default {};    // 负载    Class<? extends Payload>[] payload() default {};}

在定义注解时可声明变量用于辅助校验。上面的注解中定义了maxLength变量用于指定最大长度限制。变量可以设置默认值,使用注解时不传参数,变量就使用默认值。

2、实现校验逻辑,校验失败后返回错误提示

package com.elon.springbootdemo.manager.invalidator;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;public class FieldLengthInvalidatorImpl implements ConstraintValidator<FieldLengthInvalidator, String> {    private int maxLength = 0;    @Override    public void initialize(FieldLengthInvalidator invalidator) {        maxLength = invalidator.maxLength();    }    @Override    public boolean isValid(String fieldValue, ConstraintValidatorContext context) {        if (fieldValue.length() > maxLength) {            context.disableDefaultConstraintViolation();            context.buildConstraintViolationWithTemplate("对象属性长度超过限制。").addConstraintViolation();            // 校验失败返回false。返回true上游收集不到错误信息。            return false;        }        return true;    }}

3、在模型字段属性上增加校验的注解

public class User{    private int userId = -1;    @FieldLengthInvalidator(maxLength=10)    private String name = "";}

4、提供统一的校验方法

package com.elon.springbootdemo.manager;import java.util.ArrayList;import java.util.List;import java.util.Set;import javax.validation.ConstraintViolation;import javax.validation.Validation;import javax.validation.Validator;import javax.validation.ValidatorFactory;public class InvalidatORMgr {    private InvalidatorMgr() {            }            public static InvalidatorMgr instance() {        return InvalidatorMgrBuilder.instance;    }            public <T> List<String> validate(T model) {                ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();        Validator validator = validatorFactory.getValidator();        Set<ConstraintViolation<T>> resultSet = validator.validate(model);                List<String> messageList = new ArrayList<>();        resultSet.forEach((r)->messageList.add(r.getMessage()));                return messageList;    }            private static class InvalidatorMgrBuilder{        private static InvalidatorMgr instance = new InvalidatorMgr();    }}

5、业务层调用校验方法

        User user = new User();        user.setName("ahskahskhqlwjqlwqlwhqlhwlqjwlqhwlhqwhqlwjjqlwl");        List<String> messageList = InvalidatorMgr.instance().validate(user);        System.out.println(messageList);

invalidator注解主要用于实现长度,范围,非法字符等通用的规则校验。不适合用于做业务逻辑的校验,特定的业务校验写在业务层。 

springboot 参数验证 validation

1、综述

springboot提供了强大的基于注解的、开箱即用的验证功能,这种基于bean validation的实现和 hibernate validator类似

2、依赖

创建springboot项目,包含以下依赖

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-WEB</artifactId></dependency><dependency>     <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId></dependency> <dependency>     <groupId>com.h3Database</groupId>     <artifactId>h3</artifactId>    <version>1.4.197</version>     <scope>runtime</scope></dependency>

3、定义实体类

测试项目为了方便,直接用JPA,使用@NotBlank指定非空字段,message是验证触发后返回的信息,还有@Null、@NotNull、@NotBlank、@Email、@Max、@Min、@Size、@Negative、@DecimalMax、@DecimalMin、@Positive、@PositiveOrZero、@NegativeOrZero、@AssertTrue、@AssertFalse、@Future、@FutureOrPresent、@Past、@PastOrPresent、@Pattern

@Entitypublic class User {        @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private long id;         @NotBlank(message = "Name is mandatory")    private String name;         @NotBlank(message = "Email is mandatory")    private String email;        // standard constructors / setters / getters / toString        }

创建JPA的repository定义增删改查接口

@Repositorypublic interface UserRepository extends CrudRepository<User, Long> {}

4、创建rest controller

@RestControllerpublic class UserController {     @PostMapping("/users")    ResponseEntity<String> addUser(@Valid @RequestBody User user) {        // persisting the user        return ResponseEntity.ok("User is valid");    }         // standard constructors / other methods     }

接收到的user对象添加了@Valid,当Spring Boot发现带有@Valid注解的参数时,会自动引导默认的jsR 380验证器验证参数。当目标参数未能通过验证时,Spring Boot将抛出一个MethodArgumentNotValidException

5、实现ExceptionHandler

直接抛出异常显然是不合理的,大部分情况需要经过处理返回给前端更友好的提示信息,通过@ExceptionHandler来处理抛出的异常实现该功能

@ResponseStatus(httpstatus.BAD_REQUEST)@ExceptionHandler(MethodArgumentNotValidException.class)public Map<String, String> handleValidationExceptions(  MethodArgumentNotValidException ex) {    Map<String, String> errors = new HashMap<>();    ex.getBindingResult().getAllErrors().forEach((error) -> {        String fieldName = ((FieldError) error).getField();        String errorMessage = error.getDefaultMessage();        errors.put(fieldName, errorMessage);    });    return errors;}

MethodArgumentNotValidException作为上一步抛出的异常,当springboot执行validition触发时会调用此实现,该方法将每个无效字段的名称和验证后错误消息存储在映射中,然后它将映射作为JSON表示形式发送回客户端进行进一步处理。

6、写测试代码

使用springboot自带的插件进行测试rest controller,

@RunWith(SpringRunner.class) @WebmvcTest@AutoConfigureMockMvcpublic class UserControllerIntegrationTest {     @MockBean    private UserRepository userRepository;         @Autowired    UserController userController;     @Autowired    private MockMvc mockMvc;     //...     }

@WebMvcTest允许我们使用MockMvcRequestBuilders和MockMvcResultMatchers实现的一组静态方法测试请求和响应。测试addUser()方法,在请求体中传递一个有效的User对象和一个无效的User对象。

@Testpublic void whenPostRequestToUsersAndValidUser_thenCorrectResponse() throws Exception {    MediaType textPlainUtf8 = new MediaType(MediaType.TEXT_PLAIN, Charset.forName("UTF-8"));    String user = "{\"name\": \"bob\", \"email\" : \"bob@domain.com\"}";    mockMvc.perform(MockMvcRequestBuilders.post("/users")      .content(user)      .contentType(MediaType.APPLICATION_JSON_UTF8))      .andExpect(MockMvcResultMatchers.status().isOk())      .andExpect(MockMvcResultMatchers.content()        .contentType(textPlainUtf8));} @Testpublic void whenPostRequestToUsersAndInValidUser_thenCorrectResponse() throws Exception {    String user = "{\"name\": \"\", \"email\" : \"bob@domain.com\"}";    mockMvc.perform(MockMvcRequestBuilders.post("/users")      .content(user)      .contentType(MediaType.APPLICATION_JSON_UTF8))      .andExpect(MockMvcResultMatchers.status().isBadRequest())      .andExpect(MockMvcResultMatchers.jsonPath("$.name", Is.is("Name is mandatory")))      .andExpect(MockMvcResultMatchers.content()        .contentType(MediaType.APPLICATION_JSON_UTF8));    }}

也可以使用postman或fiddler来测试REST controller api

7、跑测试

@SpringBootApplicationpublic class Application {         public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }         @Bean    public CommandLineRunner run(UserRepository userRepository) throws Exception {        return (String[] args) -> {            User user1 = new User("Bob", "bob@domain.com");            User user2 = new User("Jenny", "jenny@domain.com");            userRepository.save(user1);            userRepository.save(user2);            userRepository.findAll().forEach(System.out::println);        };    }}

如果用没有用户名或邮箱的数据发送请求会收到返回的提示信息

{  "name":"Name is mandatory",  "email":"Email is mandatory"}

以上就是“怎么通过自定义spring invalidator注解校验数据合法性”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: 怎么通过自定义spring invalidator注解校验数据合法性

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

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

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

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

下载Word文档
猜你喜欢
  • 怎么通过自定义spring invalidator注解校验数据合法性
    今天小编给大家分享一下怎么通过自定义spring invalidator注解校验数据合法性的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面...
    99+
    2023-07-02
  • 如何通过自定义spring invalidator注解校验数据合法性
    目录自定义spring invalidator注解校验数据合法性1、定义校验属性字符串长度的注解2、实现校验逻辑,校验失败后返回错误提示3、在模型字段属性上增加校验的注解4、提供统一...
    99+
    2024-04-02
  • SpringBoot通过自定义注解实现参数校验
    目录1. 为什么要进行参数校验2. 如何实现参数校验3. 注解实现参数校验4. 自定义注解实现参数校验1. 为什么要进行参数校验 在后端进行工作时,需要接收前端传来的数据去数据库查询...
    99+
    2022-12-23
    SpringBoot自定义注解参数校验 SpringBoot参数校验 SpringBoot 注解 参数校验
  • SpringBoot如何通过自定义注解实现参数校验
    今天小编给大家分享一下SpringBoot如何通过自定义注解实现参数校验的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. ...
    99+
    2023-07-04
  • java怎么自定义注解做参数校验
    在Java中,可以使用自定义注解来进行参数校验。以下是一个简单的示例: import java.lang.annotation.El...
    99+
    2023-10-26
    java
  • Java利用自定义注解实现数据校验
    目录JSR303介绍引入依赖常用注解开启校验数据校验测试自定义的封装错误信息统一异常处理分组校验创建分组校验接口添加校验注解开启分组校验自定义校验编写自定义的校验注解编写自定义的校验...
    99+
    2024-04-02
  • 怎么在SpringBoot中通过自定义注解实现一个Token校验功能
    本篇文章为大家展示了怎么在SpringBoot中通过自定义注解实现一个Token校验功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。定义Token的注解,需要Token校验的接口,方法上加上此注解...
    99+
    2023-06-14
  • SpringBoot自定义注解API数据加密和签名校验
    api数据数据签名(MD5,SHA1) 签名枚举类SginEnum.java package com.jx.app.api.framework.annotation.enum...
    99+
    2024-04-02
  • Spring MVC如何通过添加自定义注解格式化数据
    这篇文章主要为大家展示了“Spring MVC如何通过添加自定义注解格式化数据”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Spring MVC如何通过添加自定义注解格式化数据”这篇文章吧。sp...
    99+
    2023-05-30
    springmvc
  • Java增加自定义注解进行校验入参的方法是什么
    这篇文章主要介绍“Java增加自定义注解进行校验入参的方法是什么”,在日常操作中,相信很多人在Java增加自定义注解进行校验入参的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java增加自定义注解...
    99+
    2023-07-06
  • java怎么通过注解加载自定义配置文件
    在Java中,可以使用注解来加载自定义配置文件。具体步骤如下:1. 创建一个自定义的注解,用来标记需要加载的配置文件。```java...
    99+
    2023-09-17
    java
  • Spring boot怎么实现超灵活的注解式数据校验
    本篇内容主要讲解“Spring boot怎么实现超灵活的注解式数据校验”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Spring boot怎么实现超灵活的注解式数据校验”吧!...
    99+
    2023-06-21
  • 怎么自定义@RequestBody注解获取JSON数据
    这篇文章主要介绍“怎么自定义@RequestBody注解获取JSON数据”,在日常操作中,相信很多人在怎么自定义@RequestBody注解获取JSON数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么自...
    99+
    2023-07-06
  • 怎么用Spring的spel获取自定义注解参数值
    这篇文章主要介绍了怎么用Spring的spel获取自定义注解参数值的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Spring的spel获取自定义注解参数值文章都会有所收获,下面我们一起来看看吧。spel获...
    99+
    2023-06-29
  • SpringBoot怎么通过自定义注解与异步来管理日志
    这篇文章主要介绍“SpringBoot怎么通过自定义注解与异步来管理日志”,在日常操作中,相信很多人在SpringBoot怎么通过自定义注解与异步来管理日志问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spr...
    99+
    2023-07-05
  • 怎么通过UI给C4C自定义BO创建测试数据
    本篇内容主要讲解“怎么通过UI给C4C自定义BO创建测试数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么通过UI给C4C自定义BO创建测试数据”吧!假设我在Cloud Studio里创建了...
    99+
    2023-06-04
  • vue子组件中怎么通过自定义事件向父组件传递数据
    这篇文章将为大家详细讲解有关vue子组件中怎么通过自定义事件向父组件传递数据,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。使用v-on绑定自定义事件可以让子...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作