spring3.0开发不可避免要遇到异常处理,如果只有jsp请求能捕获到异常,是不足够的, 有时候AJAX返回json数据时遇到异常。这时候默认的处理方式不能满足了, 需要自定义的方式支持同步和ajax异步异常处理。
或许大家都知道spring3的异常处理方法有:
1 以配置文件的方式进行异常管理
在配置dispacher-servlet.xml
- <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
- <property name="defaultErrorView">
- <value>jsonView</value>
- </property>
- <property name="exceptionMappings">
- <props>
- <prop key="java.lang.Exception">/common/error.jsp</prop>
- </props>
- </property>
- </bean>
配置多个异常处理的地方
2 以注解的方式配置异常管理
为了方便阅读, 把代码的地方发全一点
- @Controller
- public class ExceptionHandlerController
- {
- private final Logger log = LoggerFactory.getLogger(getClass());
- @ExceptionHandler(ManagerSecurityException.class)
- public ModelAndView handleManagerSecurityException(ManagerSecurityException e,
- HttpServletResponse response)
- throws IOException
- {
- log.info("Manager exception handler " + e.getMessage());
- response.sendError(HttpServletResponse.SC_FORBIDDEN,
- e.getMessage());
- return new ModelAndView("viewName",new HashMap());
- }
- }
这样的配置处理jstl请求jsp没有问题,
如果是jquery的 $.post的方法请求, 那么如果还是返回 error.jsp , 那在 js的success函数里则不能很好地输出显示了。
问题又来了: 如果在 handleManagerSecurityException方法的上面打上注解 @ResponeBody
那么这样又只能返回 json格式串的异常处理, 你想同步请求跳到到error.jsp又不行啦!
解决办法是这样的:定制化异常处理
- <bean id="exceptionResolver" class="com.wsd.core.web.servlet.handle.CustomSimpleMappingExceptionResolver">
- <property name="defaultErrorView">
- <value>/common/error.jsp</value>
- </property>
- <property name="exceptionMappings">
- <props>
- <prop key="java.lang.Exception">/common/error.jsp</prop>
- </props>
- </property>
- </bean>
下面我们来看看CustomSimpleMappingExceptionResolver.java是如何做到支持JSP和JSON格式返回的异常错误的
- @Override
- protected ModelAndView doResolveException(HttpServletRequest request,
- HttpServletResponse response,
- Object handler,
- Exception ex) {
- // Expose ModelAndView for chosen error view.
- String viewName = determineViewName(ex, request);
- if (viewName != null) {//JSP格式返回
- if(!(request.getHeader("accept").indexOf("application/json")>-1 || request.getHeader("X-Requested-With").indexOf("XMLHttpRequest")>-1)){//如果不是异步请求
- // Apply HTTP status code for error views, if specified.
- // Only apply it if we're processing a top-level request.
- Integer statusCode = determineStatusCode(request, viewName);
- if (statusCode != null) {
- applyStatusCodeIfPossible(request, response, statusCode);
- return getModelAndView(viewName, ex, request);
- }
- }else{//JSON格式返回
- Map<String, Object> model=new HashMap<String, Object>();
- if(this.logger.isDebugEnabled()){
- model.put("debug", true);
- }//exception
- model.put(ConfigConstants.RESULT, ex.getMessage());
- model.put("failure", true);
- try {
- response.getWriter().write("有异常啦!");
- } catch (IOException e) {
- e.printStackTrace();
- }
- return new ModelAndView();
- }
- return null;
- }
- else {
- return null;
- }
- }
这里判断了request.getHeader("accept").indexOf("application/json")是不是异步请求
下面给出同步和异步请求的Header
同步的text/html
=== MimeHeaders ===
host = localhost:8888
user-agent = Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
accept = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language = en,zh;q=0.7,en-gb;q=0.3
accept-encoding = gzip,deflate
accept-charset = ISO-8859-1,utf-8;q=0.7,*;q=0.7
keep-alive = 115
connection = keep-alive
cookie = JSESSIONID=BB7441E4B481FF64A5BCC8E6F596C330
异步的application/json
=== MimeHeaders ===
host = localhost:8888
user-agent = Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
accept = application/json, text/javascript, */*
accept-language = en,zh;q=0.7,en-gb;q=0.3
accept-encoding = gzip,deflate
accept-charset = ISO-8859-1,utf-8;q=0.7,*;q=0.7
keep-alive = 115
connection = keep-alive
content-type = application/x-www-form-urlencoded
x-requested-with = XMLHttpRequest
referer = http://localhost:8888/auth/auth/dictionary/dictionaryForm.html
cookie = JSESSIONID=A4B59EA87C9B83B71C0D455634746411
请注意
try {
response.getWriter().write("有异常啦!");
} catch (IOException e) {
e.printStackTrace();
}
return new ModelAndView();
关键就在最后这1句 return new ModelAndView();
为什么不写 return null; 或者 return new ModelAndView('jsonView', model); 呢?
因为spring3的源码里这样写着了
- protected ModelAndView processHandlerException(HttpServletRequest request,
- HttpServletResponse response,
- Object handler,
- Exception ex) throws Exception {
- // Check registerer HandlerExceptionResolvers...
- ModelAndView exMv = null;
- for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
- exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
- if (exMv != null) {
- break;
- }
- }
- if (exMv != null) {
- if (exMv.isEmpty()) {
- return null;
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv,
- ex);
- }
- WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
- return exMv;
- }
- throw ex;
- }
注意看
if (exMv != null) {
if (exMv.isEmpty()) {
return null;
}
这句和最后一句: throw ex;
如果你写 respone.getWriter().write("有异常啦"); 你也要 new一个空的ModelAndView,
上面的代码表明, 如果你 return null; 它就跑出异常 throw ex; 如果没人接收, 则会调用你配置的默认异常处理器
或者中断不做任何输出。
好了, 这样可以同时支持同步和AJAX异步请求异常处理了。
下面附上截图, 以免误人子弟~
相关推荐
spring3.0 全部jar包 spring3.0 全部jar包 spring3.0 全部jar包
《Spring 3.0就这么简单》语言简洁,实例丰富,可帮助读者迅速掌握使用Spring3.0进行开发所需的各种技能。《Spring3.0就这么简单》适合于具有一定Java编程基础的读者,以及在Java平台下进行各类软件开发的开发人员和...
spring3.0 开发包,开发J2ee,值得拥有
《Spring3.0就这么简单》主要介绍了Spring3.0的核心内容,不仅讲解了Spring3.0的基础知识,还深入讨论了SpringIoC容器、SpringAOP、使用SpringJDBC访问数据库、集成Hibernate、Spring的事务管理、SpringMVC、单元...
Spring 3.0重要特性总结如下: ◆Spring表达式(SpEL):用于bean定义的核心表达式分析器 ◆对基于注释的组件的更多支持:允许通过元注释创建注释的“快捷方式” ◆标准化的依赖性注入注释:对Java中依赖性注入的...
spring3.0的API,spring3.0的API
spring3.0 jar包
spring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 apispring3.0 api
Struts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdf
spring3.0 项目源码 spring3.0 注解 的学习,spring mvc 完整项目, 请你好好学习一下!
spring 3.0 jar包,下载无需资源分,希望大家能够用得到,另外强烈鄙视那些上传资源不完整,不经过测试的人。
spring3.0Mvc简单示例 导入即可运行
spring3.0+spring mvc3.0+mybaits3.0
Spring3.0学习文档主要讲解的是IOC和AOP 静态代理、动态代理这些内容是Spring3.0中最难理解的重点知识点
spring 3.0 必须的 jar 包。
Myeclipse8.5下搭建SSH框架(图解)Struts2.1+Spring3.0+Hibernate3.3
spring3.0 + jpa 需要的jar包 spring3.0 + jpa 需要的jar包 spring3.0 + jpa 需要的jar包
Spring 3.0 作者:陈雄华,林开雄
spring 3.0 source code project