Error Exception
Error经常是程序无法处理的 (用户引入的错误 系统的错误)
Exception 程序员引发的,能够在程序中处理, try catch / throws
优秀的处理机制
问题:怎么处理? 如何做到优秀?
二、处理方式统共分为三种:数据验证错误、错误页指派、全局异常处理
1)数据验证错误a) Hibernate Validator自身的功能
@NotNull @NotEmpty @NotBlank
@NotNull 不为空 广泛用于基础类型的判断 int double boolean
@NotBlank不为空串 广泛用于String类型的判断 string
@NotEmpty内容不为空 广泛用于集合等的判断 Map map = new HashMap(); map.put("","");
org.springframework.boot spring-boot-starter-validation
@Data @AllArgsConstructor
public class Guest {
@NotBlank(message = "嘉宾名字不能为空")
private String name;
@NotBlank
private String role;
}
public class GuestValidTest {
public static void main(String[] args) {
//通过Validation创建一个validator实例
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
//创建一个不符合要求的bean
Guest guest = new Guest("","");
//开始验证 接收验证结果
Set> violationSet = validator.validate(guest);
for(ConstraintViolation violation : violationSet){
System.out.println(violation.getPropertyPath() + "," + violation.getMessage());
}
}
}
这是校验框架的模式之一,
“普通模式” (遍历所有属性,不符合校验规则都返回)
“快速失败模式” (遍历属性时,有一个不符合校验规则,即返回)
public class GuestValidTest {
public static void main(String[] args) {
//通过Validation创建一个validator实例 (普通模式)
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
//创建一个快速失败模式的实例
Validator validatorFastFail = Validation.byDefaultProvider().configure()
.addProperty("hibernate.validator.fail_fast","true").
buildValidatorFactory().getValidator();
//创建一个不符合要求的bean
Guest guest = new Guest("","");
//开始验证 接收验证结果
Set> violationSet = validator.validate(guest);
for(ConstraintViolation violation : violationSet){
System.out.println(violation.getPropertyPath() + "," + violation.getMessage());
}
System.out.println("==============================");
Set> violationFastFailSet = validatorFastFail.validate(guest);
for(ConstraintViolation violation : violationFastFailSet){
System.out.println(violation.getPropertyPath() + "," + violation.getMessage());
}
}
}
b)在springboot的集成使用
使用默认的处理方式
@RestController
public class GuestController {
@PostMapping("/guest")
public String add(@Valid Guest guest){
return "Success";
}
}
自定义效果通过ult来处理
@PostMapping("/guest")
public String add(@Valid Guest guest, BindingResult result){
if(result.getErrorCount()>0){
List fieldErrorList = result.getFieldErrors();
StringBuffer stringBuffer = new StringBuffer();
for(FieldError fieldError : fieldErrorList){
stringBuffer.append(fieldError.getField());
stringBuffer.append("t");
stringBuffer.append(fieldError.getDefaultMessage());
stringBuffer.append("n");
}
return stringBuffer.toString();
}
return "Success";
}
springboot支持通过配置文件设置校验信息,文件名为ValidationMessages.properties,位置在resources下,在bean中的注解属性中通过{key}来获取对应的value
@NotBlank(message = "{guest.name.notblank}")
private String name;
guest.name.notblank=嘉宾名字不能为空 from properties2)错误页指派
方式1:
创建/public/error/404.html页面,注意只支持静态页面
方式2:
创建/templates/error/404.html页面,支持动态页面,并且优先级比/public/error目录高。
注意: 可以通过4xx.html页面,代表所有以4开头的错误码要查找的页面(400,401,402…),5xx.html同理。
当404.html和4xx.html同时存在,优先显示精确的错误码页面,即为404.html
方式3:(优先级高于方式二)
创建自定义的错误视图解析器,实现ErrorViewResolver接口
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status,
Map model) {
if(status.equals(HttpStatus.NOT_FOUND)){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/resolver404");
return modelAndView;
}
return null;
}
}
方式4:(优先级高于方式三)
使用WebServerFactoryCustomizer来注册bean,通过更改错误码的处理路径,来指定不同的页面。
@Configuration
public class MyCustomizer {
@Bean
public WebServerFactoryCustomizer customizer(){
return new WebServerFactoryCustomizer() {
@Override
public void customize(ConfigurableWebServerFactory factory) {
ErrorPage errorPage = new ErrorPage(HttpStatus.NOT_FOUND,"/error404");
factory.addErrorPages(errorPage);
}
};
}
}
@Controller
public class MyErrorController {
@RequestMapping("/error404")
public String error404(){
return "error404";
}
}
3)全局异常处理
通过@ControllerAdvise注解监听所有在controller中出现的异常,执行@ExceptionHandler注解的方法,跳转错误页。
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handler(Exception e){
ModelAndView mv = new ModelAndView();
mv.setViewName("/error");
mv.addObject("message",e.getMessage());
return mv;
}
}
ERROR
这里是/templates/error.html
现在出现异常了
message
测试用例
@RequestMapping("/testError")
public String error() throws Exception{
throw new Exception("测试异常");
}



