在SpringMVC中拥有一套非常强大的异常处理机制,SpringMVC通过HandlerExceptionResolver处理程序的异常,包括请求映射,数据绑定以及目标方法的执行时发生的异常。
在容器启动好,进入DispatcherServlet之后,会对HandlerExceptionResolver进行初始化,
会默认的从DispatcherServlet.properties中找到对应的异常处理类:
#默认的处理类
org.springframework.web.servlet.HandlerExceptionResolver=
#处理@ExceptionHandler
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
#解析@ResponseStatus注释类型的异常(不常用,会把方法直接定义为异常)
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
#按照不同类型分别对异常进行解析
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
AbstractHandlerMethodExceptionResolver是ExceptionHandlerExcpetionResolver父类
SimpleMappingExceptionResolver:通过配置的异常类和view的对应关系解析异常
@Controller public class ExceptionController { @RequestMapping("/exception") public String exception(@RequestParam("name")String name){ return "admin"; } @ExceptionHandler(Exception.class) public ModelAndView handleException(Exception ex){ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("ex",ex); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); ex.printStackTrace(pw); System.out.println(sw.toString()); // 日志记录 return modelAndView; } }
如果@ExceptionHandler在控制器中,则只能处理本控制器的异常
2.统一异常处理
@ControllerAdvice 是Spring3.2提供的新注解,它是对Controller的增强,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。
@ExceptionHandler
加在Controller中 :只处理当前控制器的异常,优先级最高
加在ControllerAdvice中 :处理全局异常,精准匹配则优先级其次高
@ControllerAdvice public class GeneralExceptionHandler { @ExceptionHandler(Exception.class) public ModelAndView handleException(Exception ex){ System.out.println("全局异常处理"); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("ex",ex); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); ex.printStackTrace(pw); System.out.println(sw.toString()); // 日志记录 return modelAndView; } }
如果是接口开发或者处理ajax请求则返回的是json数据
@ExceptionHandler(Exception.class)
public ModelAndView handleException(HttpServletRequest request,
HttpServletResponse reponse, Exception ex,
HandlerMethod handle){
System.out.println("全局异常处理");
// 如果当前请求是ajax就返回json
// 1.根据用户请求的处理方法,是否是一个返回json的处理方法
//RestController restAnnotation = handle.getClass().getAnnotation(RestController.class); // 获得类上面的某个注解
//ResponseBody responseBody = handle.getMethod().getAnnotation(ResponseBody.class);//获得方法上面的某个注解
// if(restAnnotation!=null || responseBody!=null){ }
// 2.可以根据请求头中的类型Content-Type包含application/json
if(request.getHeader("Accept").indexOf("application/json")>-1){
// 可以直接输出json reponse.getWriter().write(); 或者集成jackson
// 集成jackson的方式:
//ModelAndView 同时支持视图返回和json返回
// 这种方式就是返回json
ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
// 通常会根据不同的异常返回不同的编码
modelAndView.addObject("code", HttpStatus.INTERNAL_SERVER_ERROR.value());
modelAndView.addObject("message",ex.getMessage());
return modelAndView;
}
else{
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex", ex);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
System.out.println(sw.toString()); // 日志记录
return modelAndView;
}
}
404则需要在web.xml中配置
<error-page>
<error-code></error-code>
<location></location>
</error-page>
将映射地址指向静态资源文件夹,springMvc将不会将此映射作为handler
<mvc:resources mapping="/**/*.html" location="">