Spring MVC 数据校验
Spring MVC
Spring MVC 提供了两种数据校验的⽅式:
1、基于 Validator 接⼝。
基于 Validator 接⼝的⽅式需要⾃定义 Validator 验证器,每⼀条数据的验证规则需要开发者⼿动完成,
2、使⽤ Annotation JSR - 303 标准进⾏校验。
使⽤ Annotation JSR - 303 标准则不需要⾃定义验证器,通过注解的⽅式可以直接在实体类中添加每个属性的验证规则,这种⽅式更加⽅便,实际开发中推荐使⽤。
Annotation JSR - 303 标准
使⽤ Annotation JSR - 303 标准进⾏验证,需要导⼊⽀持这种标准的依赖 jar ⽂件,这⾥我们使⽤
Hibernate Validator。
<!--JSR303数据校验支持;tomcat7及以上的服务器,
tomcat7以下的服务器:el表达式。额外给服务器的lib包中替换新的标准的el
-->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
给pojo指定校验规则
public class User {
@NotBlank
private String username;
@Length(min = 4,max = 8)
private String password;
@Min(22)
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
@valid
增加@Valid注解,验证失败会报错。
Servlet.service() for servlet springDispatcherServlet threw exception
java.lang.NoSuchMethodError:javax.el.ExpressionFactory.newInstance()Ljavax/el/ExpressionFactory;
@RequestMapping("useradd")
public String add(@Valid User user, BindingResult bindingResult, Model model){
Map<String,Object> map=new HashMap<>();
if(bindingResult.hasErrors()){
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println(fieldError.getField());
System.out.println(fieldError.getDefaultMessage());
System.out.println(fieldError);
map.put(fieldError.getField(),fieldError.getDefaultMessage());
}
model.addAttribute("map",map);
return "user";
}
return "success";
}
BindingResult
public interface BindingResult extends Errors
1.Spring MVC 是通过对处理方法签名的规约来保存校验结果的:前一个表单/命令对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是 BindingResult 或 Errors 类型,这两个类都位于 org.springframework.validation 包中
2.需校验的 Bean 对象和其绑定结果对象或错误对象是成对出现的,它们之间不允许声明其他的入参
3.Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或 getFieldErrors(String field)
4.BindingResult 扩展了 Errors 接口
在目标方法中获取校验结果
在表单/命令对象类的属性中标注校验注解,在处理方法对应的入参前添加 @Valid,Spring MVC 就会实施校验并将校验结果保存在被校验入参对象之后的 BindingResult 或 Errors 入参中。
常用方法:
FieldError getFieldError(String field)
List getFieldErrors()
Object getFieldValue(String field)
Int getErrorCount()
获取提示信息返回给页面
@RequestMapping("useradd")
public String add(@Valid User user, BindingResult bindingResult, Model model){
Map<String,Object> map=new HashMap<>();
if(bindingResult.hasErrors()){
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println(fieldError.getField());
System.out.println(fieldError.getDefaultMessage());
System.out.println(fieldError);
map.put(fieldError.getField(),fieldError.getDefaultMessage());
}
model.addAttribute("map",map);
return "user";
}
return "success";
}
异常处理
- ExceptionHandlerExceptionResolver
- 主要处理 Handler 中用 @ExceptionHandler 注解定义的方法。
- [email protected] 注解定义的方法优先级问题:例如发生的是NullPointerException,但是声明的异常有 RuntimeException 和 Exception,此候会根据异常的最近继承关系找到继承深度最浅的那个 @ExceptionHandler 注解方法,即标记了 RuntimeException 的方法
- ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话,会找 @ControllerAdvice 中的@ExceptionHandler 注解方法
- @ExceptionHandler
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
- @ControllerAdvice
@ControllerAdvice
public class ExceptionHandle {
/**
* 异常处理
* @ExceptionHandler 指定处理异常
* 要携带的异常信息不能给参数位置写model
* 可以使用ModelAndView
* 多个能处理该异常的方法 精确优先 顺序优先
*/
@ExceptionHandler(Exception.class)
public ModelAndView excetption(Exception e){
ModelAndView modelAndView=new ModelAndView();
System.out.println(e);
modelAndView.addObject("err",e);
modelAndView.setViewName("/500.jsp");
return modelAndView;
}
}
- ResponseStatusExceptionResolver
- 在异常及异常父类中找到 @ResponseStatus 注解,然后使用这个注解的属性进行处理。
- 定义一个 @ResponseStatus 注解修饰的异常类
- 若在处理器方法中抛出了上述异常:若ExceptionHandlerExceptionResolver 不解析上述异常。
- 由于触发的异常 UnauthorizedException 带有@ResponseStatus 注解。
- 因此会被ResponseStatusExceptionResolver 解析到。
- 最后响应HttpStatus.UNAUTHORIZED 代码给客户端。HttpStatus.UNAUTHORIZED 代表响应码401,无权限。 关于其他的响应码请参考 HttpStatus 枚举类型源码。
如果没有异常处理类捕获,那么会交由SpringMVC来处理
/**
* @author pyc 自定义异常,标注异常的响应状态码,异常拦截器根据异常注解的状态码决定跳转的错误页面
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}
public NotFoundException(String message) {
super(message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
- 抛出异常
@RequestMapping(value="/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if(i==13){
throw new UsernameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver...");
return "success";
}
- 异常处理类捕获异常 判断 是否有ResponseStatus注解
// 异常处理方法 ModelAndView 不能在参数上注入 ==>
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(HttpServletRequest req, Exception e) throws Exception {
logger.error("Requst URL : {},Exception : {}", req.getRequestURL(),e);
// 如果异常有ResponseStatus的注解
if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class)!=null){
//抛出异常 springboot有 指定默认的处理页面 寻找 error文件夹下的对应 400 500异常
throw e;
}
// 视图模型
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("url", req.getRequestURL());
modelAndView.addObject("exception", e);
modelAndView.setViewName("error/error");
return modelAndView;
}
校验规则详解
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
@Min(value) 被注解的元素必须是⼀个数字,其值必须⼤于等于指定的最⼩值
@Max(value) 被注解的元素必须是⼀个数字,其值必须⼩于于等于指定的最⼤值
@Email 被注解的元素必须是电⼦邮箱地址
@Pattern 被注解的元素必须符合对应的正则表达式
@Length 被注解的元素的⼤⼩必须在指定的范围内
上一篇: Spring mvc 参数校验
下一篇: Lucene 实现简单的搜索
推荐阅读
-
Spring之跨重定向请求传递数据
-
Spring mvc 分步式session的实例详解
-
Spring MVC自定义日期类型转换器实例详解
-
从原理层面掌握@SessionAttribute的使用【一起学Spring MVC】
-
深入了解数据校验:Bean Validation 2.0(JSR380)
-
Intellij IDEA 2019 + Java Spring MVC + Hibernate学习笔记(1)
-
Druid数据源SQL数据库与Spring监控
-
Spring引入外部属性文件配置数据库连接的步骤详解
-
spring MVC扩展和SSM整合
-
Spring Boot项目添加外部Jar包以及配置多数据源的完整步骤