zoukankan      html  css  js  c++  java
  • 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.定义自己的异常处理类

    Java代码  收藏代码
    1. import java.io.IOException;  
    2. import java.lang.reflect.Method;  
    3. import java.util.Collections;  
    4. import java.util.List;  
    5. import java.util.Map;  
    6.   
    7. import javax.servlet.ServletException;  
    8. import javax.servlet.http.HttpServletRequest;  
    9. import javax.servlet.http.HttpServletResponse;  
    10.   
    11. import org.springframework.core.annotation.AnnotationUtils;  
    12. import org.springframework.http.HttpInputMessage;  
    13. import org.springframework.http.HttpOutputMessage;  
    14. import org.springframework.http.HttpStatus;  
    15. import org.springframework.http.MediaType;  
    16. import org.springframework.http.converter.HttpMessageConverter;  
    17. import org.springframework.http.server.ServletServerHttpRequest;  
    18. import org.springframework.http.server.ServletServerHttpResponse;  
    19. import org.springframework.util.StringUtils;  
    20. import org.springframework.web.bind.annotation.ResponseBody;  
    21. import org.springframework.web.bind.annotation.ResponseStatus;  
    22. import org.springframework.web.method.HandlerMethod;  
    23. import org.springframework.web.servlet.ModelAndView;  
    24. import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;  
    25.   
    26. /** 
    27.  * 不必在Controller中对异常进行处理,抛出即可,由此异常解析器统一控制。<br> 
    28.  * ajax请求(有@ResponseBody的Controller)发生错误,输出JSON。<br> 
    29.  * 页面请求(无@ResponseBody的Controller)发生错误,输出错误页面。<br> 
    30.  * 需要与AnnotationMethodHandlerAdapter使用同一个messageConverters<br> 
    31.  * Controller中需要有专门处理异常的方法。 
    32.  *  
    33.  * @author dongjian 
    34.  *  
    35.  * */  
    36. public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver {  
    37.       
    38.     private String defaultErrorView;  
    39.       
    40.     public String getDefaultErrorView() {  
    41.         return defaultErrorView;  
    42.     }  
    43.   
    44.     public void setDefaultErrorView(String defaultErrorView) {  
    45.         this.defaultErrorView = defaultErrorView;  
    46.     }  
    47.   
    48.     /*** 
    49.      * 异常后跳转到页面 
    50.      */  
    51.     protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) {  
    52.           
    53.         if (handlerMethod == null) {  
    54.             return null;  
    55.         }  
    56.           
    57.         Method method = handlerMethod.getMethod();  
    58.   
    59.         if (method == null) {  
    60.             return null;  
    61.         }  
    62.           
    63.         ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception);  
    64.           
    65.         ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class);  
    66.         if (responseBodyAnn != null) {  
    67.             try {  
    68.                 ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class);  
    69.                 if (responseStatusAnn != null) {  
    70.                     HttpStatus responseStatus = responseStatusAnn.value();  
    71.                     String reason = responseStatusAnn.reason();  
    72.                     if (!StringUtils.hasText(reason)) {  
    73.                         response.setStatus(responseStatus.value());  
    74.                     } else {  
    75.                         try {  
    76.                             response.sendError(responseStatus.value(), reason);  
    77.                         } catch (IOException e) { }  
    78.                     }  
    79.                 }  
    80.               
    81.                 return handleResponseBody(returnValue, request, response);  
    82.             } catch (Exception e) {  
    83.                 return null;  
    84.             }  
    85.         }  
    86.           
    87.         if(returnValue.getViewName() == null){  
    88.             returnValue.setViewName(defaultErrorView);  
    89.         }  
    90.           
    91.         return returnValue;  
    92.           
    93.     }  
    94.       
    95.       
    96.     /** 
    97.      * 异常后 返回json 
    98.      * @param returnValue 
    99.      * @param request 
    100.      * @param response 
    101.      * @return 
    102.      * @throws ServletException 
    103.      * @throws IOException 
    104.      */  
    105.     @SuppressWarnings({ "unchecked""rawtypes" })  
    106.     private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    107.         Map value = returnValue.getModelMap();  
    108.         HttpInputMessage inputMessage = new ServletServerHttpRequest(request);  
    109.         List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();  
    110.         if (acceptedMediaTypes.isEmpty()) {  
    111.             acceptedMediaTypes = Collections.singletonList(MediaType.ALL);  
    112.         }  
    113.         MediaType.sortByQualityValue(acceptedMediaTypes);  
    114.         HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);  
    115.         Class<?> returnValueType = value.getClass();  
    116.         List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();  
    117.         if (messageConverters != null) {  
    118.             for (MediaType acceptedMediaType : acceptedMediaTypes) {  
    119.                 for (HttpMessageConverter messageConverter : messageConverters) {  
    120.                     if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {  
    121.                         messageConverter.write(value, acceptedMediaType, outputMessage);  
    122.                         return new ModelAndView();  
    123.                     }  
    124.                 }  
    125.             }  
    126.         }  
    127.         if (logger.isWarnEnabled()) {  
    128.             logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);  
    129.         }  
    130.         return null;  
    131.     }  
    132.   
    133. }  

     2.在spring MVC 配置中添加如下配置

     

    Java代码  收藏代码
    1.     <!--  ResponseBody 的类型 -->  
    2. <bean  
    3.     id="messageConverters" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
    4.          <property name="supportedMediaTypes">  
    5.              <list>  
    6.                  <value>application/json;charset=UTF-8</value>  
    7.              </list>  
    8.          </property>  
    9.  </bean>  
    10.   
    11.   
    12. <bean id="handlerAdapter"  
    13.     class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
    14.     <property name="cacheSeconds" value="0" />  
    15.     <property name="messageConverters" ref="messageConverters" />  
    16. </bean>  
    17.   
    18. <!-- 设置自定义异常处理 -->  
    19.    <bean id="handlerExceptionResolver" class="com.chengkun.base.exception.AnnotationHandlerMethodExceptionResolver">  
    20.     <property name="defaultErrorView" value="error.jsp"/><!-- 错误页面 -->  
    21.     <property name="messageConverters" ref="messageConverters"/> <!--JSON 处理的messageConverters->  
    22. </bean>  

     3.修改web.xml 禁止自动注册,让其使用我们自定义的类

    Java代码  收藏代码
    1. <servlet>  
    2.         <servlet-name>spring-mvc</servlet-name>  
    3.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    4.         <init-param>  
    5.             <param-name>contextConfigLocation</param-name>  
    6.             <param-value>classpath:spring/spring-mvc.xml</param-value>  
    7.         </init-param>  
    8.           
    9.         <!-- 取消其自动注册的异常解析器 -->  
    10.         <init-param>  
    11.             <param-name>detectAllHandlerExceptionResolvers</param-name>  
    12.             <param-value>false</param-value>  
    13.         </init-param>  
    14.         <load-on-startup>1</load-on-startup>  
    15.     </servlet>  

     4.在BaseController 中加入异常控制,所有controller必须继承BaseController

    Java代码  收藏代码
    1. /** 
    2.     * 异常控制,可以根据不同的异常类型 在此定义不同的错误消息和操作 
    3.     * */  
    4.     @ExceptionHandler(Exception.class)  
    5.     @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)  
    6.     public ModelAndView handleException(Exception ex, HttpServletRequest request) {  
    7.         return new ModelAndView().addObject(new ResultPojo(500));  
    8.     }  

     

     

     

  • 相关阅读:
    BZOJ3509: [CodeChef] COUNTARI
    BZOJ3790: 神奇项链
    BZOJ3527: [Zjoi2014]力
    BZOJ2194: 快速傅立叶之二
    解题:BJOI 2006 狼抓兔子
    解题:SDOI 2017 数字表格
    解题:TJOI 2015 弦论
    解题:NOI 2016 优秀的拆分
    解题:AHOI2017/HNOI2017 礼物
    解题:洛谷2093 JZPFAR
  • 原文地址:https://www.cnblogs.com/hanjun0612/p/9779811.html
Copyright © 2011-2022 走看看