SpringMVC实现参数校验

在 Web 应用的三层架构中,确保在表述层(Presentation Layer)对数据进行检查和校验是非常重要的。正确的数据校验可以确保业务逻辑层(Business Logic Layer)基于有效和合法的数据进行处理,同时将错误的数据隔离在业务逻辑层之外。这有助于提高系统的健壮性、安全性和可维护性。

校验概述

JSR-303是Java EE 6中的一项子规范,也被称为Bean Validation。这个规范主要用于对Java Bean中的字段值进行验证。JSR-303提供了一套注解和API,方便开发者在实体类中对字段进行验证,以确保数据的合法性。

在JSR-303中,内置了许多常用的约束规则,如@NotNull(非空验证)、@Size(长度验证)、@Range(范围验证)等。这些注解可以直接应用于实体类的字段上,以声明验证规则。同时,JSR-303还提供了验证器(Validator)接口,用于执行验证操作。开发者可以通过注入Validator实例,或者使用Validation工具类来触发验证。

在Spring MVC中,JSR-303得到了很好的支持。开发者可以在控制器的方法参数上使用JSR-303的注解,以实现表单数据的自动验证。如果参数不满足约束条件,Spring MVC会抛出MethodArgumentNotValidException异常,并将错误信息绑定到相应的字段上。

常用注解

@NotNull:确保字段值不为null。
@NotBlank:用于String类型参数校验,检查字符串不能为null且去除首尾空格后长度大于0。
@NotEmpty:主要用于集合校验,校验集合不能为null且size大于0,也可以用于String的校验,确保字
@Null:确保字段值为null。
@AssertTrue 和 @AssertFalse:用于boolean字段,确保字段值为true或false。
@Min 和 @Max:用于Number和String字段,确保字段值在指定的范围内。
@DecimalMin 和 @DecimalMax:用于BigDecimal,BigInteger,String,byte,short,int,long字段,确保字段值在指定的小数范围内。需要注意的是,小数验证存在精度问题。
@Size:用于Collection,Map,Array,String字段,确保字段的长度(或大小)在指定的范围内。
@Digits:用于BigDecimal,BigInteger,String,byte,short,int,long字段,验证值的数字构成是否合法。它有两个参数,integer表示整数部分的数字的位数,fraction表示小数部分的数字的位数。
@Email:用于String字段,验证字段值是否为有效的电子邮件地址。
@Past 和 @Future:用于日期和时间字段,确保日期在过去或未来。
@Pattern:用于String字段,验证字段值是否匹配指定的正则表达式。
@Range:控制一个数值的范围,如数字、日期等。
@Valid:递归地对关联对象进行校验,如果关联对象是个集合或者数组,那么对其中的元素进行递归校验;如果是一个map,则对其中的值部分进行校验。
@CreditCardNumber:信用卡验证。
@URL:验证一个字符串是否符合URL格式。
@ScriptAssert:使用脚本语言进行自定义验证。

@NotNull、@NotEmpty和@NotBlank注解说明

@NotNull、@NotEmpty和@NotBlank都是Java中的注解,用于在运行时检查属性值是否符合特定条件。它们的使用场景如下:

@NotNull:这个注解用于基本数据类型和它们的包装类(如Integer、Long、Double等),以及String类型。当它被用在String类型上时,表示该数据不能为null,但可以为空字符串。这个注解一般用在基本数据类型的非空校验上,如果被其标注的字段使用了@Size、@Max或@Min等注解,那么还可以对字段的数值大小进行控制。此外,@NonNull是JSR 305(缺陷检查框架)的注解,用于方法或构造函数的参数上,表明所修饰的参数不能为null。它会在代码检查(静态检查)时给出一个风险警告,但运行时不会报错。
@NotEmpty:这个注解用于String、Collection集合、Map、数组等类型。加了@NotEmpty注解的参数不能为null,而且长度或大小必须大于0。这个注解一般用在集合类上。

@NotBlank:这个注解只能用于String类型。加了@NotBlank注解的字符串不能为null,而且去除两端空白字符后的长度(trimmed length)必须大于0。这个注解通常用于前端发送过来的数据,先进行校验处理,再进行逻辑判断。

总结来说,@NotNull、@NotEmpty和@NotBlank的使用场景主要取决于你想要验证的数据类型和约束条件。@NotNull主要用于基本数据类型和String的非空检查,@NotEmpty主要用于集合类,而@NotBlank则主要用于String类型,要求字符串不为null且去除空白字符后的长度大于0。在实际开发中,一定要根据具体需求选择合适的注解,否则可能会导致验证逻辑出错。

操作演示

1.导入依赖

<!--validation-api接口的实现-->
<dependency>  
    <groupId>org.hibernate.validator</groupId>  
    <artifactId>hibernate-validator</artifactId>  
    <version>6.2.5.Final</version>  
</dependency>  
<!--Java Bean Validation 的规范接口-->
<dependency>  
    <groupId>javax.validation</groupId>  
    <artifactId>validation-api</artifactId>  
    <version>2.0.1.Final</version>  
</dependency>
<!--Java 注解处理器,它用于在编译时检查 JSR-303 注解的正确性和一致性-->
<dependency>
	<groupId>org.hibernate.validator</groupId>
	<artifactId>hibernate-validator-annotation-processor</artifactId>
	<version>6.2.5.Final</version>
</dependency>

2.校验实体对象参数
实体类

@Data
public class User {

    @NotBlank
    private String name;
    @NotNull(message = "年龄最小1岁,最大100岁")
    @Range(min = 1 , max = 100)
    private Integer age;
    @NotNull(message = "邮箱不能为空,并且要符合规范")
    @Email
    private String email;
    @NotNull
    @Size(min = 2,max = 50)
    private String address;
    @Past
    private Date birthday;
    @NotEmpty
    private List<String> users;
}

controller

//实体对象校验
//在实体类参数和 BindingResult 之间不能有任何其他参数, BindingResult可以接受错误信息,避免信息抛出!
//@Validated 或 @Valid 代表应用校验注解!
@PostMapping("validateObject")
private String validateObject(@Validated @RequestBody User user, BindingResult result, Model model) {
	if (result.hasErrors()) {
		String errorMsg = Objects.requireNonNull(result.getFieldError()).toString();
		System.out.println(errorMsg);
		model.addAttribute("msg",errorMsg);
		return "error";
	}
	System.out.println("user=" + user);
	model.addAttribute("msg",user);
	return "success";
}

说明:
@Validated注解是SpringMVC提供的。
@Valid注解是JSR-303提供的。

3.基本类型校验

    //基本类型校验
@GetMapping("validate")
public String validateBasic(@RequestBody @Min(18) Integer age, @RequestBody @NotBlank String name) {
    return "success";
}

配置校验器

说明:一般情况下不需要配置,SpringMVC已经配置好默认校验器

基于xml配置方式
LocalValidatorFactoryBean 是 Spring 框架提供的一个类,它实现了 ValidatorFactory 接口。在 Spring 环境中,LocalValidatorFactoryBean 通常被用作 Bean Validation 的默认实现。Spring 的自动配置通常会为你创建一个 LocalValidatorFactoryBean 实例,并将其配置为应用的默认 ValidatorFactory。这意味着,当你在 Spring 控制器或服务中使用 @Valid 或 @Validated 注解时,背后实际上是 LocalValidatorFactoryBean 在执行验证逻辑。

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<mvc:annotation-driven validator="validator"/>

基于配置类方式
构建 ValidatorFactory 实例。
ValidatorFactory 是一个工厂类,用于生产 Validator 实例,这些 Validator 实例用于执行实际的验证逻辑。当你需要在非 Spring 环境中进行 Bean Validation,或者当 Spring 的自动配置不能满足你的需求时,你可以使用这个方法手动配置和获取 Validator。

@Configuration  
@EnableWebMvc  
public class WebConfig implements WebMvcConfigurer {  
  
    @Bean  
    public Validator validator() {  
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();  
        return factory.getValidator();  
    }  
}

结论:
Validation.buildDefaultValidatorFactory():这是 Bean Validation API 的标准方法,用于在非 Spring 环境中创建 ValidatorFactory。在 Spring 中,除非你有特殊需求需要绕过 Spring 的自动配置,否则通常不会直接使用这个方法。
LocalValidatorFactoryBean:这是 Spring 框架特有的类,用于在 Spring 应用中作为默认的 ValidatorFactory。在 Spring 应用中,你通常不需要直接操作 LocalValidatorFactoryBean,因为 Spring 会自动为你配置和注入它。但是,如果你需要自定义验证器的配置(例如,更改消息插值器、遍历提供者等),你可以创建一个 LocalValidatorFactoryBean 的 Bean 并进行相应的配置。

4.集合校验

//集合校验
@PostMapping("validateList")
public Object validateList(@Valid @RequestBody List<@Positive User> users, BindingResult result) {
	if (result.hasErrors()) {
		Map<String,Object> map = new HashMap<>();
		map.put("code","400");
		map.put("msg","参数校验失败,不符合规则");
		return map;
	}
	System.out.println(users);
	return users;
}

自定义校验注解

1.定义一个注解类,并使用@interface关键字。
2.在注解类上添加@Constraint注解,并指定校验器类。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyCustomValidator.class)
public @interface MyCustomValidation {

    String message() default "该字段不能为空";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

3.创建一个实现ConstraintValidator接口的校验器类,实现校验逻辑。

public class MyCustomValidator implements ConstraintValidator<MyCustomValidation,String> {

    @Override
    public void initialize(MyCustomValidation constraintAnnotation) {
        //可以在这里进行一些初始化操作
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 自定义校验逻辑:检查字符串是否为空或仅包含空白字符
        return value != null && !value.trim().isEmpty();
    }
}

4.在需要校验的字段上应用自定义注解。

public class CustomValidationEntity {

    @MyCustomValidation
    private String customField;
}

全局异常校验配置

为了优雅地处理校验失败的情况,你可以实现一个全局异常处理器来捕获MethodArgumentNotValidException异常,并从中提取错误信息。这个异常是如果控制器方法形参不满足约束条件,Spring MVC会抛出MethodArgumentNotValidException异常,并将错误信息绑定到相应的字段上。例如:

@ControllerAdvice  
public class GlobalExceptionHandler {  
  
    @ExceptionHandler(MethodArgumentNotValidException.class)  
    public ResponseEntity<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {  
        BindingResult bindingResult = ex.getBindingResult();  
        Map<String, String> errors = new HashMap<>();  
        for (FieldError fieldError : bindingResult.getFieldErrors()) {  
            errors.put(fieldError.getField(), fieldError.getDefaultMessage());  
        }  
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);  
    }  
}

在这个例子中,GlobalExceptionHandler类使用@ControllerAdvice注解标记为一个全局异常处理器。handleValidationExceptions方法则用于处理MethodArgumentNotValidException异常。它从BindingResult中提取错误信息,并将这些信息作为响应返回给客户端。

这样,当客户端发送一个包含无效数据的请求时,服务器会返回一个包含错误信息的响应,而不是直接抛出异常。

原文地址:https://www.cnblogs.com/lisong0626/p/18048253

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


开发过程中是不可避免地会出现各种异常情况的,例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题,甚至直接导致程序崩溃。因此,在开发过程中,合理处理异常、避免异常产生、以及对异常进行有效的调试是非常重要的。 对于异常的处理,一般分为两种方式: 编程式异常处理:是指在代
说明:使用注解方式实现AOP切面。 什么是AOP? 面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能。 AOP底层使用动态代理。 AOP术语 连接点
Spring MVC中的拦截器是一种可以在请求处理过程中对请求进行拦截和处理的机制。 拦截器可以用于执行一些公共的操作,例如日志记录、权限验证、数据转换等。在Spring MVC中,可以通过实现HandlerInterceptor接口来创建自定义的拦截器,并通过配置来指定拦截器的应用范围和顺序。 S
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:ServletContext、HttpSession、HttpServletRequest、PageContext。 ServletContext 共享域:
文件上传 说明: 使用maven构建web工程。 使用Thymeleaf技术进行服务器页面渲染。 使用ResponseEntity实现下载文件的功能。 @Controller public class FileDownloadAndUpload { @GetMapping(&quot;/file/d
创建初始化类,替换web.xml 在Servlet3.0环境中,Web容器(Tomcat)会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。 Spring提供了这个接口的实现,名为SpringS
在 Web 应用的三层架构中,确保在表述层(Presentation Layer)对数据进行检查和校验是非常重要的。正确的数据校验可以确保业务逻辑层(Business Logic Layer)基于有效和合法的数据进行处理,同时将错误的数据隔离在业务逻辑层之外。这有助于提高系统的健壮性、安全性和可维护
什么是事务? 事务(Transaction)是数据库操作最基本单元,逻辑上一组操作,要么都成功,要么都失败,如果操作之间有一个失败所有操作都失败 。 事务四个特性(ACID) 原子性 一组操作要么都成功,要么都失败。 一致性 一组数据从事务1合法状态转为事务2的另一种合法状态,就是一致。 隔离性 事
什么是JdbcTemplate? Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。 准备工作 引入jdbcTemplate的相关依赖: 案例实操 创建jdbc.properties文件,配置数据库信息 jdbc.driver=com.mysql.cj.
SpringMVC1.MVC架构MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范是将业务逻辑、数据、显示分离的方法来写代码MVC主要作用是:降低了视图和业务逻辑之间的双向耦合MVC是一个架构模型,不是一种设计模式。1.model(模型)数据模型,提供要展示的数据,因此包
SpringMVC学习笔记1.SpringMVC应用1.1SpringMVC简介​SpringMVC全名叫SpringWebMVC,是⼀种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于SpringFrameWork的后续产品。​MVC全名是ModelViewController,是模型(model)-视图(view)-控制器(co
11.1数据回显基本用法数据回显就是当用户数据提交失败时,自动填充好已经输入的数据。一般来说,如果使用Ajax来做数据提交,基本上是没有数据回显这个需求的,但是如果是通过表单做数据提交,那么数据回显就非常有必要了。11.1.1简单数据类型简单数据类型,实际上框架在这里没有
一、SpringMVC简介1、SpringMVC中重要组件DispatcherServlet:前端控制器,接收所有请求(如果配置/不包含jsp)HandlerMapping:解析请求格式的.判断希望要执行哪个具体的方法.HandlerAdapter:负责调用具体的方法.ViewResovler:视图解析器.解析结果,准备跳转到具体的物
1.它们主要负责的模块Spring主要应用于业务逻辑层。SpringMVC主要应用于表现层。MyBatis主要应用于持久层。2.它们的核心Spring有三大核心,分别是IOC(控制反转),DI(依赖注入)和AOP(面向切面编程)。SpringMVC的核心是DispatcherServlet(前端控制器)。MyBatis的核心是ORM(对
3.注解开发Springmvc1.使用注解开发要注意开启注解支持,2.注解简化了,处理映射器和处理适配器,只用去管视图解析器即可案例代码:1.web.xml,基本不变可以直接拿去用<!--调用DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name>
拦截器概述SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。过滤器servlet规范中的一部分,任何javaweb工程都可以使用
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="
学习内容:1、SSH&SSM2、Spring3、Struts2&SpringMVC4、Hibernate&MyBatis学习产出:1.SSH和SSM都是有Spring框架的,他们两个差不多。2.Spring分为四个模块,持久层,表示层,检测层,还有核心层,核心层分为2个关键核心功能。分别为,控制反转(IOC),依赖注入(DI),和面向切面编程
一、SpringMVC项目无法引入js,css的问题具体原因是css和js等被SpringMVC拦截了:解决方案:在spring-mvc.xml中配置<mvc:default-servlet-handler/><?xmlversion="1.0"encoding="UTF-8"?><beansxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
开发环境:Eclipse/MyEclipse、Tomcat8、Jdk1.8数据库:MySQL前端:JavaScript、jQuery、bootstrap4、particles.js后端:maven、SpringMVC、MyBatis、ajax、mysql读写分离、mybatis分页适用于:课程设计,毕业设计,学习等等系统介绍