spring MVC 统一异常处理(webapi和web分开处理)
转载: http://blog.csdn.net/m13321169565/article/details/7641978
http://blog.csdn.net/ethan_fu/article/details/44624171
在使用web开发和API 开发都使用到异常的处理,web 异常后跳到指定的错误页面,那么API或AJAX调用需要返回JSON的错误信息,所以我们需要一个统一的异常处理机制来管理这些异常!
1.定义自己的异常处理类
- import java.io.IOException;
- import java.lang.reflect.Method;
- import java.util.Collections;
- import java.util.List;
- import java.util.Map;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.core.annotation.AnnotationUtils;
- import org.springframework.http.HttpInputMessage;
- import org.springframework.http.HttpOutputMessage;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.http.converter.HttpMessageConverter;
- import org.springframework.http.server.ServletServerHttpRequest;
- import org.springframework.http.server.ServletServerHttpResponse;
- import org.springframework.util.StringUtils;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.bind.annotation.ResponseStatus;
- import org.springframework.web.method.HandlerMethod;
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
- /**
- * 不必在Controller中对异常进行处理,抛出即可,由此异常解析器统一控制。<br>
- * ajax请求(有@ResponseBody的Controller)发生错误,输出JSON。<br>
- * 页面请求(无@ResponseBody的Controller)发生错误,输出错误页面。<br>
- * 需要与AnnotationMethodHandlerAdapter使用同一个messageConverters<br>
- * Controller中需要有专门处理异常的方法。
- *
- * @author dongjian
- *
- * */
- public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver {
- private String defaultErrorView;
- public String getDefaultErrorView() {
- return defaultErrorView;
- }
- public void setDefaultErrorView(String defaultErrorView) {
- this.defaultErrorView = defaultErrorView;
- }
- /***
- * 异常后跳转到页面
- */
- protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) {
- if (handlerMethod == null) {
- return null;
- }
- Method method = handlerMethod.getMethod();
- if (method == null) {
- return null;
- }
- ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception);
- ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class);
- if (responseBodyAnn != null) {
- try {
- ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class);
- if (responseStatusAnn != null) {
- HttpStatus responseStatus = responseStatusAnn.value();
- String reason = responseStatusAnn.reason();
- if (!StringUtils.hasText(reason)) {
- response.setStatus(responseStatus.value());
- } else {
- try {
- response.sendError(responseStatus.value(), reason);
- } catch (IOException e) { }
- }
- }
- return handleResponseBody(returnValue, request, response);
- } catch (Exception e) {
- return null;
- }
- }
- if(returnValue.getViewName() == null){
- returnValue.setViewName(defaultErrorView);
- }
- return returnValue;
- }
- /**
- * 异常后 返回json
- * @param returnValue
- * @param request
- * @param response
- * @return
- * @throws ServletException
- * @throws IOException
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- Map value = returnValue.getModelMap();
- HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
- List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
- if (acceptedMediaTypes.isEmpty()) {
- acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
- }
- MediaType.sortByQualityValue(acceptedMediaTypes);
- HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
- Class<?> returnValueType = value.getClass();
- List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
- if (messageConverters != null) {
- for (MediaType acceptedMediaType : acceptedMediaTypes) {
- for (HttpMessageConverter messageConverter : messageConverters) {
- if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
- messageConverter.write(value, acceptedMediaType, outputMessage);
- return new ModelAndView();
- }
- }
- }
- }
- if (logger.isWarnEnabled()) {
- logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);
- }
- return null;
- }
- }
2.在spring MVC 配置中添加如下配置
- <!-- ResponseBody 的类型 -->
- <bean
- id="messageConverters" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- </value>
- </list>
- </property>
- </bean>
- <bean id="handlerAdapter"
- class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- <property name="cacheSeconds" value="0" />
- <property name="messageConverters" ref="messageConverters" />
- </bean>
- <!-- 设置自定义异常处理 -->
- <bean id="handlerExceptionResolver" class="com.chengkun.base.exception.AnnotationHandlerMethodExceptionResolver">
- <property name="defaultErrorView" value="error.jsp"/><!-- 错误页面 -->
- <property name="messageConverters" ref="messageConverters"/> <!--JSON 处理的messageConverters->
- </bean>
3.修改web.xml 禁止自动注册,让其使用我们自定义的类
- <servlet>
- <servlet-name>spring-mvc</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:spring/spring-mvc.xml</param-value>
- </init-param>
- <!-- 取消其自动注册的异常解析器 -->
- <init-param>
- <param-name>detectAllHandlerExceptionResolvers</param-name>
- <param-value>false</param-value>
- </init-param>
- </load-on-startup>
- </servlet>
4.在BaseController 中加入异常控制,所有controller必须继承BaseController
- /**
- * 异常控制,可以根据不同的异常类型 在此定义不同的错误消息和操作
- * */
- @ExceptionHandler(Exception.class)
- @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
- public ModelAndView handleException(Exception ex, HttpServletRequest request) {
- ));
- }
spring MVC 统一异常处理(webapi和web分开处理)的更多相关文章
- Spring MVC 统一异常处理
Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...
- 使用Spring MVC统一异常处理实战
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- 使用Spring MVC统一异常处理实战<转>
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- 使用Spring MVC统一异常处理实战(转载)
原文地址:http://blog.csdn.net/ufo2910628/article/details/40399539 种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMa ...
- Spring MVC统一异常处理
实际上Spring MVC处理异常有3种方式: (1)一种是在Controller类内部使用@ExceptionHandler使用注解实现异常处理: 可以在Controller内部实现更个性化点异常处 ...
- spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)
spring 封装了非常强大的异常处理机制.本文选取@ControllerAdvice + @ExceptionHandler 这种零配置(全注解),作为异常处理解决方案! @ControllerAd ...
- 【转】使用Spring MVC统一异常处理实战
方法一:使用SimpleMappingExceptionResolver实现异常处理 //在Spring的配置文件applicationContext.xml中增加以下内容: <bean cla ...
- 从零开始学 Java - Spring MVC 统一异常处理
看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或者你已经练功到了孤独求败,等了半辈子 ...
- 使用Spring MVC统一异常处理
http://blog.csdn.net/ufo2910628/article/details/40399539
随机推荐
- R 语言-基础
R语言 1997年成为GNU项目 开源免费 R官方网址 www.r-project.org R是数据分析领域的语言小巧灵活,通过扩展包来增强功能绘图功能代码简单 开发环境R + RStudio 1.数 ...
- excel的宏与VBA入门(一)——基础概念
一.概述 "记录宏"其实就是将工作的一系列操作结果录制下来,并命名存储(相当于VB中一个子程序). 宏其实就是VBA写的,但是可以通过录制的方法制作宏,做好的宏你可以查看相应的VB ...
- kali黑客渗透测试基础环境准备
1.apt-get install python-nmap 2.apt-get install python-setuptools 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 ...
- [LOJ#6198]谢特[后缀数组+trie+并查集]
题意 给你一个长度为 \(n\) 的字符串,问 \(LCP(i,j)+(w_i\ xor\ w_j)\) 的最大值,其中 \(LCP\) 表示两个后缀的最长公共前缀. \(n\le 10^5\) 分析 ...
- C#字符串截取、获取当前电脑时间、判断输入日期对错 随手记
字符串截取:这个就当复习了,看意见就可以 //身份证生日截取 //Console.WriteLine("请输入18位身份证号:"); //string x = Console.Re ...
- C#_Stream
IO操作基本上需要用到Stream相关的子类,因此这类问题在CSDN问得也是比较多.其实对于Stream来说,操作起来比较简单,只要对细节的处理稍微注意一下,相信在使用它的时候也会得心应手. 对于St ...
- Svn 提示错误:previous operation has not finished 解决方案
svn提交遇到恶心的问题,可能是因为上次cleanup中断后,进入死循环了. 解决方案: 找到你项目的.svn文件,查看是否存在wc.db 网上下载SQLite Expert工具,手动打开wc.db, ...
- Jenkins 构建运行java程序
我们将在Jenkins建立执行一个简单的 HelloWorld 应用程序,构建和运行Java程序.打开网址:http://localhost:8080/jenkins 第1步- 转到Jenkins 仪 ...
- js中文汉字按拼音排序
JavaScript 提供本地化文字排序,比如对中文按照拼音排序,不需要程序显示比较字符串拼音. String.prototype.localeCompare 在不考虑多音字的前提下,基本可以完美实现 ...
- hexo搭建
http://blog.csdn.net/gdutxiaoxu/article/details/53576018