一、全局异常处理
项目中,可能会抛出多个异常,我们不可以直接将异常的堆栈信息展示给用户:
- 用户体验不好
- 不安全
针对异常,可以自定义异常处理。
比如说文件超限:
可以使用@ControllerAdvice 注释类,这是一个增强版Controller,主要用来做增强版数据处理
@ControllerAdvice
//在该注解下定义方法处理异常
public class ExceptionHandle {
@ExceptionHandler(Exception.class) //处理什么异常
public ModelAndView fileuploadSizeLimit(Exception e){
ModelAndView mv=new ModelAndView("error");
mv.addObject("error",e.getMessage());
return mv;
}
}
二、数据校验
服务端校验why?
理解客户端校验和服务端校验各自的目的。
- 客户端校验 主要是为了提高用户体验。B/S架构中,用户可以方便地拿到请求地址,然后直接发送请求,传递非法参数。
- 服务端校验 有效保证数据安全与完整性
1. 普通校验
加入依赖:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
配置bean:
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" id="validatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
driven修改:
<mvc:annotation-driven validator="validatorFactoryBean"/>
model下定义Student:
eg.注解
@Size(min=2,max=10,message = “学生名称长度介于2-10之间”)
package org.kk.fileupload.model;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* @program: fileupload
* @description:
* @author: zjx
* @create: 2022-01-17 22:42
**/
public class Student {
//对于model,可以通过注解增加校验规则
@NotNull
@Size(min=2,max=10)
private String username;
@NotNull
private Integer id;
@Email
private String email;
@Size(max=150)
private Integer age;
}
写对应Controller:
注意点:接收的Student对象需要有注解@Validated,通过 BindingResult result可以查看异常信息
message的定义也可以使用properties文件:
首先先解决编码问题——setting改UTF-8
放在resources文件夹下:
key可以随便定义
student.id.notnull=id 不能为空
student.name.notnull=name 不能为空
student.name.size=学生名称长度介于2-10之间
那么student类可以改为:
//对于model,可以通过注解增加校验规则
@NotNull(message = "{student.name.notnull}")
@Size(min=2,max=10,message = "{student.name.size}")
private String name;
@NotNull(message = "{student.id.notnull}")
private Integer id;
@Email
private String email;
@Size(max=150)
private Integer age;
配置bean:
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="reloadableResourceBundleMessageSource">
<property name="basenames"> <!--有很多个配置文件 而basename说明配置文件有好多个-->
<list>
<value>classpath:MyMessage</value> <!--没有后缀!!!-->
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
<property name="cacheSeconds" value="300"/>
</bean>
validatorFactoryBean里面也要增加属性:
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" id="validatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="reloadableResourceBundleMessageSource"/>
</bean>
2. 分组校验
//对于model,可以通过注解增加校验规则
@NotNull(message = "{student.name.notnull}",groups = {ValidationGroup1.class, ValidationGroup2.class})
@Size(min=2,max=10,message = "{student.name.size}",groups = ValidationGroup1.class)
private String name;
@NotNull(message = "{student.id.notnull}",groups = ValidationGroup2.class)
private Integer id;
@Email
private String email;
@Size(max=150)
private Integer age;
在group1里面,只会校验name.notnull,name.size。。。
所以校验时要指定分组(controller中指定)@Validated(ValidationGroup1.class)
public class StudentController {
@PostMapping("/student")
@ResponseBody
public void addStudent(@Validated(ValidationGroup1.class) Student student, BindingResult result)
{