Spring MVC全局异常后返回JSON异常数据
2015-08-29 18:37
603 查看
Spring MVC全局异常后返回JSON异常数据
问题:
当前项目是作为手机APP后台支持,使用spring mvc + mybaits + shiro进行开发。后台服务与手机端交互是发送JSON数据。如果后台发生异常,会直接返回异常页面,显示异常内容,如果是404请求不到资源或者500这类服务器的问题,可能会导致返回404和500异常页面,手机端的处理就非常麻烦,为了解决这个问题,就需要做全局的异常处理。解决方案:
(1)自定义或者使用spring自带的各种异常处理器
例如spring基于注解的异常解析器AnnotationHandlerMethodExceptionResolver 、spring自带全局异常处理器SimpleMappingExceptionResolver、自定义实现spring的全局异常解析器HandlerExceptionResolver来处理。AnnotationHandlerMethodExceptionResolver目前我所知道的是需要在方法上定义异常的类型,如果异常类型多了,写起代码太麻烦,所以我认为不好用。(那位大侠知道不用定义异常类型就处理所有异常,可以留言告诉我,谢谢!)
spring自带全局异常处理器SimpleMappingExceptionResolver也是比较繁琐的,需要配置的地方太多了,不喜欢用。
自定义实现spring的全局异常解析器HandlerExceptionResolver来处理我认为是最方便的,当然,这个是针对我目前的业务场景而言,并不是绝对的。
由于java的异常机制,如果发生大量异常,对jvm的性能会产生很大的影响,轻则性能下降10%,重则导致jvm内存溢出,我个人认为能不抛异常就最好不抛,所以,我主要使用自定义实现spring的全局异常解析器HandlerExceptionResolver来处理业务问题。
(2)自定义实现spring的全局异常解析器HandlerExceptionResolver
2.1 只需要在spring-mvc的配置文件中定义一个全局异常处理类 <!-- 全局异常处理 --> <bean id="exceptionHandler" class="com.aaa.bbb.exception.DefaultExceptionHandler" />2.2 实现HandlerExceptionResolver(第一种实现方式)
这种方式需要下载温少写的fastjson,我用的是1.2.6版本,可以百度后自己下载。
public class DefaultExceptionHandler implements HandlerExceptionResolver { private static Logger log = LoggerFactory.getLogger(DefaultExceptionHandler.class); public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView mv = new ModelAndView(); /* 使用FastJson提供的FastJsonJsonView视图返回,不需要捕获异常 */ FastJsonJsonView view = new FastJsonJsonView(); Map<String, Object> attributes = new HashMap<String, Object>(); attributes.put("code", "1000001"); attributes.put("msg", ex.getMessage()); view.setAttributesMap(attributes); mv.setView(view); log.debug("异常:" + ex.getMessage(), ex); return mv; } }2.2 实现HandlerExceptionResolver(第二种实现方式)
public class DefaultExceptionHandler implements HandlerExceptionResolver { private static Logger log = LoggerFactory.getLogger(DefaultExceptionHandler.class); public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView mv = new ModelAndView(); /* 使用response返回 */ response.setStatus(HttpStatus.OK.value()); //设置状态码 response.setContentType(MediaType.APPLICATION_JSON_VALUE); //设置ContentType response.setCharacterEncoding("UTF-8"); //避免乱码 response.setHeader("Cache-Control", "no-cache, must-revalidate"); try { response.getWriter().write("{\"success\":false,\"msg\":\"" + ex.getMessage() + "\"}"); } catch (IOException e) { log.error("与客户端通讯异常:"+ e.getMessage(), e); } log.debug("异常:" + ex.getMessage(), ex); return mv; } }
到此,spring mvc全局异常处理返回json就搞定了,发生异常后,返回的都是json数据,不会再有烦人的异常内容。不过这还不算完整,需要在web.xml中加入异常代码404或者500的处理才能算完。
(1)web页面异常处理配置
1.1 <exception-type>java.lang.Throwable</exception-type>表示发生java.lang.Throwable类型的异常,<location>/error_500</location>表示到/error_500地址处理,
例如用户请求【http://www.a.com/user/login/getUser】 ,应用名称是user,如果请求发生java.lang.Throwable,那么请求会转到【http://www.a.com/user/error_500】
1.2 <error-code>404</error-code>表示发生404请求失败,<location>/error_404</location>表示到/error_404处理,
例如用户请求【http://www.a.com/user/login/getUser】,应用名称是user ,如果用户请求发生404异常,请求资源找不到,那么请求会转到【http://www.a.com/user/error_404】
<!-- web异常页面处理 --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error_500</location> </error-page> <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error_404</location> </error-page> <error-page> <error-code>500</error-code> <location>/error_500</location> </error-page> <error-page> <error-code>501</error-code> <location>/error_500</location> </error-page> <error-page> <error-code>502</error-code> <location>/error_500</location> </error-page> <error-page> <error-code>404</error-code> <location>/error_404</location> </error-page> <error-page> <error-code>403</error-code> <location>/error_404</location> </error-page> <error-page> <error-code>400</error-code> <location>/error_404</location> </error-page>
(2)后台处理
如果发生以上异常,请求会转到【http://www.a.com/user/error_404】,那么在后台就需要做相应的处理,处理方式就是在Controller层定义处理异常的方法
/** * 请求异常 * @return * @throws Exception * String */ @RequestMapping(value = "/error_404", produces = "text/html;charset=UTF-8") @ResponseBody public String error_404() throws Exception { return "{\"msg\":\"找不到页面\",\"code\":\"1000001\"}"; } /** * 服务器异常 * @return * String */ @RequestMapping(value ="/error_500", produces = "text/html;charset=UTF-8") public String error_500() { <pre name="code" class="java"> return "{\"msg\":\"服务器处理失败\",\"code\":\"1000002\"}"; }
最后,基本上所有的异常都能被捕获,能够出现异常时,友好的提示用户端,也能避免服务器端抛异常导致的问题。
相关文章推荐
- Java 反射 Reflection
- 【ssh】struts2中action接收参数的方法
- 关于安装JDK不当--找不到或无法加载主类 com.sun.tools.javac.Main问题
- Java基础知识强化04:判断101~200之间有多少素数
- JAVA基础学习(一)--JAVA入门和JDK的安装与配置
- Java学习笔记之——多线程(一)
- 是时候抛弃 Eclipse 转向 IntelliJ IDEA了
- eclipse里面java文件J为空心
- JAVA SimpleDateFormat 中英文时间格式化转换
- 【转】java虚拟机机制总结
- Java中类的加载、连接和初始化
- 《JAVA 核心技术 基础知识》 第十章 笔记
- java基础之数据类型的转换
- Java集合类详解
- 深入浅出Java回调机制
- Java—IO流程的介绍
- Java中抽象类也能实例化
- Java中对象创建和构造方运行顺序?
- Java SE入门 Lesson 01
- 10种简单的Java性能优化