Spring MVC全局异常处理
2015-11-04 14:47
447 查看
今天翻看项目发现异常类中有一个CommonExceptionHandler,却在配置文件中找不到任何有配置的地方,于是搜了一把资料,整理一下。
Spring3.0中有两种异常处理机制,一种是实现HandlerExceptionResolver接口,一种是在Controller类中使用@ExceptionHandler注解,第一种方法可以实现全局异常控制,第二种方法更加灵活,个性化,但是不统一,我之前看的项目中就是用的第一种方法。
1. 基于HandlerExceptionResolver接口的异常处理:
使用这种方法只需要复写 resolveException方法就可以了,该方法返回一个ModelAndView对象,该方法内部对异常的类型做判断,然后返回合适的ModelAndView对象,如果该方法返回了null,则spring会继续寻找其他实现了HandlerExceptionResolver接口的bean,就是说spring会搜索所有注册在其环境中的实现了HandlerExceptionResolver接口的Bean,逐个执行,直到返回了一个ModelAndView对象。(注意该自定义全局异常类一般用注解
@Component,表示模糊不好分层的注入,或者在配置文件xml中使用<bean/>结点声明。)
举例:
这种写法,错误码直接返回到前台,前台jsp页面获取到之后,进行相应的判断,给出相对应的提示,如果前台页面没有相应的判断,则会直接输入相应的错误信息在页面上。
也可以用一下写法,出现异常之后跳转到一个写好的提示页面:
public class CustomExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object object, Exception exception) {
if(exception instanceof IOException){
return new ModelAndView("errors/ioException");
}else if(exception instanceof SQLException){
return new ModelAndView("errors/sqlException");
}
return null;
}
}
4000
其中 errors/ioException 和 errors/sqlException 都是jsp页面。
spring 默认也提供了一个全局异常处理类SimpleMappingExceptionResolver,它也是HandlerExceptionResolver的实现类,如果要使用,只需要在xml中配置即可。
(以下转载自此处,点击跳转)
例如:
<span style="color:#3333FF;"> <!-- 全局异常配置 start 控制器异常处理-->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">errors/webException</prop>
<prop key="java.lang.Throwable">errors/rmsException</prop>
</props>
</property>
<property name="statusCodes">
<props>
<prop key="errors/webException">500</prop>
<prop key="errors/rmsException">404</prop>
</props>
</property>
<!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->
<property name="warnLogCategory" value="WARN"></property>
<!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 -->
<property name="defaultErrorView" value="errors/error"></property>
<!-- 默认HTTP状态码 -->
<property name="defaultStatusCode" value="500"></property>
</bean>
<!-- 全局异常配置 end --> </span>
通过SimpleMappingExceptionResolver我们可以将不同的异常映射到不同的jsp页面(通exceptionMappings属性的配置),同时我们也可以为所有的异常指定一个默认的异常提示页面(通过defaultErrorView属性的配置),如果所抛出的异常在exceptionMappings中没有对应的映射,则Spring将用此默认配置显示异常信息(注意这里配置的异常显示界面均仅包括主文件名,至于文件路径和后缀已经在viewResolver中指定)
<property name="defaultErrorView" value="errors/error"></property>
一个典型的异常显示页面如下:
exception 实在SimpleMappingExceptionResolver 被存放到request中的,具体可以查看源代码。
如果SimpleMappingExceptionResolver无法满足异常处理的需要,我们可以针对
HandlerExceptionResolver接口实现自己异常处理类,这同样非常简单(只需要实现一个
resolveException方法)。
如果有ViewResolver,则制定的jsp页面必须在那个页面下,到时候如果找不到页面,可以根据错误提示再调整页面路径
2..基于@ExceptionHandler的异常处理:
该方法需要定义在Controller内部,然后创建一个方法并用@ExceptionHandler注解来修饰用来处理异常,这个方法基本和 @RequestMapping修饰的方法差不多,只是可以多一个类型为Exception的参数,@ExceptionHandler中可以添加一个或多个异常的类型,如果为空的话则认为可以触发所有的异常类型错误。
示例:
<span style="color:#3333FF;">@Controller
public class ExceptionHandlerController {
@ExceptionHandler(value={IOException.class,SQLException.class})
public String exp(Exception ex,HttpServletRequest request) {
request.setAttribute("exception", ex);
return "/error.jsp";
}
</span>
Spring3.0中有两种异常处理机制,一种是实现HandlerExceptionResolver接口,一种是在Controller类中使用@ExceptionHandler注解,第一种方法可以实现全局异常控制,第二种方法更加灵活,个性化,但是不统一,我之前看的项目中就是用的第一种方法。
1. 基于HandlerExceptionResolver接口的异常处理:
使用这种方法只需要复写 resolveException方法就可以了,该方法返回一个ModelAndView对象,该方法内部对异常的类型做判断,然后返回合适的ModelAndView对象,如果该方法返回了null,则spring会继续寻找其他实现了HandlerExceptionResolver接口的bean,就是说spring会搜索所有注册在其环境中的实现了HandlerExceptionResolver接口的Bean,逐个执行,直到返回了一个ModelAndView对象。(注意该自定义全局异常类一般用注解
@Component,表示模糊不好分层的注入,或者在配置文件xml中使用<bean/>结点声明。)
举例:
@Component public class CommonExceptionHandler implements HandlerExceptionResolver { private static final Logger logger = LoggerFactory.getLogger(CommonExceptionHandler.class); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try { response.reset(); response.setContentType("text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); if (ex instanceof UnAuthenticatedException || ex instanceof NoAuthorityException || ex instanceof TimeoutException || ex instanceof ServiceException) { logger.warn("hander Exception:{}, Message is {}", ex.getClass(), ex.getMessage()); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); writer.print(ex.getMessage()); } else if (ex instanceof SystemShutDownException) { logger.warn("hander Exception:{}, Message is {}", ex.getClass(), ex.getMessage()); response.setStatus(HttpServletResponse.SC_FORBIDDEN); writer.print(ex.getMessage()); } else { // 其他异常,返回500状态码 logger.error(ex.getMessage(), ex); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); writer.print("System error"); } } catch (Exception e) { //logger.error(e.getMessage(), e); return null; } return new ModelAndView(); } }
这种写法,错误码直接返回到前台,前台jsp页面获取到之后,进行相应的判断,给出相对应的提示,如果前台页面没有相应的判断,则会直接输入相应的错误信息在页面上。
也可以用一下写法,出现异常之后跳转到一个写好的提示页面:
public class CustomExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object object, Exception exception) {
if(exception instanceof IOException){
return new ModelAndView("errors/ioException");
}else if(exception instanceof SQLException){
return new ModelAndView("errors/sqlException");
}
return null;
}
}
4000
其中 errors/ioException 和 errors/sqlException 都是jsp页面。
spring 默认也提供了一个全局异常处理类SimpleMappingExceptionResolver,它也是HandlerExceptionResolver的实现类,如果要使用,只需要在xml中配置即可。
(以下转载自此处,点击跳转)
例如:
<span style="color:#3333FF;"> <!-- 全局异常配置 start 控制器异常处理-->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">errors/webException</prop>
<prop key="java.lang.Throwable">errors/rmsException</prop>
</props>
</property>
<property name="statusCodes">
<props>
<prop key="errors/webException">500</prop>
<prop key="errors/rmsException">404</prop>
</props>
</property>
<!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->
<property name="warnLogCategory" value="WARN"></property>
<!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 -->
<property name="defaultErrorView" value="errors/error"></property>
<!-- 默认HTTP状态码 -->
<property name="defaultStatusCode" value="500"></property>
</bean>
<!-- 全局异常配置 end --> </span>
通过SimpleMappingExceptionResolver我们可以将不同的异常映射到不同的jsp页面(通exceptionMappings属性的配置),同时我们也可以为所有的异常指定一个默认的异常提示页面(通过defaultErrorView属性的配置),如果所抛出的异常在exceptionMappings中没有对应的映射,则Spring将用此默认配置显示异常信息(注意这里配置的异常显示界面均仅包括主文件名,至于文件路径和后缀已经在viewResolver中指定)
<property name="defaultErrorView" value="errors/error"></property>
一个典型的异常显示页面如下:
<span style="color:#3333FF;"><html> <head><title>Exception!</title></head> <body> <% Exception ex = (Exception)request.getAttribute("exception"); %> <H2>Exception: <%= ex.getMessage();%></H2> <P/> <% ex.printStackTrace(new java.io.PrintWriter(out)); %> </body> </html> </span>
exception 实在SimpleMappingExceptionResolver 被存放到request中的,具体可以查看源代码。
如果SimpleMappingExceptionResolver无法满足异常处理的需要,我们可以针对
HandlerExceptionResolver接口实现自己异常处理类,这同样非常简单(只需要实现一个
resolveException方法)。
如果有ViewResolver,则制定的jsp页面必须在那个页面下,到时候如果找不到页面,可以根据错误提示再调整页面路径
2..基于@ExceptionHandler的异常处理:
该方法需要定义在Controller内部,然后创建一个方法并用@ExceptionHandler注解来修饰用来处理异常,这个方法基本和 @RequestMapping修饰的方法差不多,只是可以多一个类型为Exception的参数,@ExceptionHandler中可以添加一个或多个异常的类型,如果为空的话则认为可以触发所有的异常类型错误。
示例:
<span style="color:#3333FF;">@Controller
public class ExceptionHandlerController {
@ExceptionHandler(value={IOException.class,SQLException.class})
public String exp(Exception ex,HttpServletRequest request) {
request.setAttribute("exception", ex);
return "/error.jsp";
}
</span>
相关文章推荐
- 分享微信开发Html5轻游戏中的几个坑
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- 如何优雅地处理前端异常?
- C#异常处理详解
- Zend的MVC机制使用分析(二)
- ASP.NET MVC 4 捆绑和缩小实例介绍
- ASP.NET MVC中将控制器分离到类库的实现
- asp.net实现在非MVC中使用Razor模板引擎的方法
- ASP.NET MVC中的AJAX应用
- 为ASP.NET MVC及WebApi添加路由优先级
- ASP.NET MVC中图表控件的使用方法
- ASP.NET MVC的四种验证编程方式
- ASP.NET MVC 3仿Server.Transfer效果的实现方法
- 如何在MVC应用程序中使用Jquery
- ASP.NET MVC小结之基础篇(二)
- ASP.NET小结之MVC, MVP, MVVM比较以及区别(一)
- Asp.net实现MVC处理文件的上传下载功能实例教程
- ASP.NET MVC小结之基础篇(一)