全局异常处理

方式一最垃圾:使用 @ ExceptionHandler 注解

使用该注解有一个不好的地方就是:进行异常处理的方法必须与出错的方法在同一个Controller里面。使用如下:

@Controller      
public class GlobalController {               

   /**    
     * 用于处理异常的    
     * @return    
     */      
    @ExceptionHandler({MyException.class})       
    public String exception(MyException e) {       
        System.out.println(e.getMessage());       
        e.printStackTrace();       
        return "exception";       
    }       

    @RequestMapping("test")       
    public void test() {       
        throw new MyException("出错了!");       
    }                    
}

方式二:实现 HandlerExceptionResolver 接口

  1. package org.jeecgframework.core.common.exception;

  2. import java.io.IOException;

  3. import java.io.PrintWriter;

  4. import java.io.StringWriter;

  5. import java.util.HashMap;

  6. import java.util.Map;

  7.  
  8. import javax.servlet.http.HttpServletRequest;

  9. import javax.servlet.http.HttpServletResponse;

  10.  
  11. import org.apache.log4j.Logger;

  12. import org.jeecgframework.core.common.model.json.AjaxJson;

  13. import org.jeecgframework.core.util.ExceptionUtil;

  14. import org.jeecgframework.core.util.JSONHelper;

  15. import org.jeecgframework.core.util.oConvertUtils;

  16. import org.jeecgframework.web.system.service.SystemService;

  17. import org.springframework.beans.factory.annotation.Autowired;

  18. import org.springframework.stereotype.Component;

  19. import org.springframework.web.servlet.HandlerExceptionResolver;

  20. import org.springframework.web.servlet.ModelAndView;

  21.  
  22. /**

  23. * spring mvc 全局处理异常捕获 根据请求区分ajax和普通请求,分别进行响应.

  24. * 第一、异常信息输出到日志中。

  25. * 第二、截取异常详细信息的前50个字符,写入日志表中t_s_log。

  26. */

  27. @Component

  28. public class GlobalExceptionResolver implements HandlerExceptionResolver {

  29. @Autowired

  30. private SystemService systemService;

  31. //记录日志信息

  32. private static final Logger log = Logger

  33. .getLogger(GlobalExceptionResolver.class);

  34. //记录数据库最大字符长度

  35. private static final int WIRTE_DB_MAX_LENGTH = 1500;

  36. //记录数据库最大字符长度

  37. private static final short LOG_LEVEL = 6;

  38. //记录数据库最大字符长度

  39. private static final short LOG_OPT = 3;

  40. /**

  41. * 对异常信息进行统一处理,区分异步和同步请求,分别处理

  42. */

  43. public ModelAndView resolveException(HttpServletRequest request,

  44. HttpServletResponse response, Object handler, Exception ex) {

  45. boolean isajax = isAjax(request,response);

  46. Throwable deepestException = deepestException(ex);

  47. return processException(request, response, handler, deepestException, isajax);

  48. }

  49. /**

  50. * 判断当前请求是否为异步请求.

  51. */

  52. private boolean isAjax(HttpServletRequest request, HttpServletResponse response){

  53. return oConvertUtils.isNotEmpty(request.getHeader("X-Requested-With"));

  54. }

  55. /**

  56. * 获取最原始的异常出处,即最初抛出异常的地方

  57. */

  58. private Throwable deepestException(Throwable e){

  59. Throwable tmp = e;

  60. int breakPoint = 0;

  61. while(tmp.getCause()!=null){

  62. if(tmp.equals(tmp.getCause())){

  63. break;

  64. }

  65. tmp=tmp.getCause();

  66. breakPoint++;

  67. if(breakPoint>1000){

  68. break;

  69. }

  70. }

  71. return tmp;

  72. }

  73. /**

  74. * 处理异常.

  75. * @param request

  76. * @param response

  77. * @param handler

  78. * @param deepestException

  79. * @param isajax

  80. * @return

  81. */

  82. private ModelAndView processException(HttpServletRequest request,

  83. HttpServletResponse response, Object handler,

  84. Throwable ex, boolean isajax) {

  85. //步骤一、异常信息记录到日志文件中.

  86. log.error("全局处理异常捕获:", ex);

  87. //步骤二、异常信息记录截取前50字符写入数据库中.

  88. logDb(ex);

  89. //步骤三、分普通请求和ajax请求分别处理.

  90. if(isajax){

  91. return processAjax(request,response,handler,ex);

  92. }else{

  93. return processNotAjax(request,response,handler,ex);

  94. }

  95. }

  96. /**

  97. * 异常信息记录截取前50字符写入数据库中

  98. * @param ex

  99. */

  100. private void logDb(Throwable ex) {

  101. //String exceptionMessage = getThrowableMessage(ex);

  102. String exceptionMessage = "错误异常: "+ex.getClass().getSimpleName()+",错误描述:"+ex.getMessage();

  103. if(oConvertUtils.isNotEmpty(exceptionMessage)){

  104. if(exceptionMessage.length() > WIRTE_DB_MAX_LENGTH){

  105. exceptionMessage = exceptionMessage.substring(0,WIRTE_DB_MAX_LENGTH);

  106. }

  107. }

  108. systemService.addLog(exceptionMessage, LOG_LEVEL, LOG_OPT);

  109. }

  110. /**

  111. * ajax异常处理并返回.

  112. * @param request

  113. * @param response

  114. * @param handler

  115. * @param deepestException

  116. * @return

  117. */

  118. private ModelAndView processAjax(HttpServletRequest request,

  119. HttpServletResponse response, Object handler,

  120. Throwable deepestException){

  121. ModelAndView empty = new ModelAndView();

  122. //response.setContentType("application/json");

  123. response.setHeader("Cache-Control", "no-store");

  124. AjaxJson json = new AjaxJson();

  125. json.setSuccess(true);

  126. json.setMsg(deepestException.getMessage());

  127. PrintWriter pw = null;

  128. try {

  129. pw=response.getWriter();

  130. pw.write(JSONHelper.bean2json(json));

  131. pw.flush();

  132. } catch (IOException e) {

  133. e.printStackTrace();

  134. }finally{

  135. pw.close();

  136. }

  137. empty.clear();

  138. return empty;

  139. }

  140. /**

  141. * 普通页面异常处理并返回.

  142. * @param request

  143. * @param response

  144. * @param handler

  145. * @param deepestException

  146. * @return

  147. */

  148. private ModelAndView processNotAjax(HttpServletRequest request,

  149. HttpServletResponse response, Object handler, Throwable ex) {

  150. String exceptionMessage = getThrowableMessage(ex);

  151. Map<String, Object> model = new HashMap<String, Object>();

  152. model.put("exceptionMessage", exceptionMessage);

  153. model.put("ex", ex);

  154. return new ModelAndView("common/error", model);

  155. }

  156. /**

  157. * 返回错误信息字符串

  158. *

  159. * @param ex

  160. * Exception

  161. * @return 错误信息字符串

  162. */

  163. public String getThrowableMessage(Throwable ex) {

  164. StringWriter sw = new StringWriter();

  165. PrintWriter pw = new PrintWriter(sw);

  166. ex.printStackTrace(pw);

  167. return sw.toString();

  168. }

  169.  


 

<!-- 异常处理类 -->
    <bean id="exceptionHandler"
        class="org.jeecgframework.core.common.exception.GlobalExceptionResolver" />
@Component注解。

-----------------

package com.vehsy.utils;


import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.vehsy.guodianmall.GuoDianMallConstant;
import com.vehsy.pub.exception.VehsyRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IDEA
 * author:王起飞(Felice)
 * Date:2018/4/28
 * Time:10:17
 */
public class GuoDianMallExceptionHandler extends AbstractExceptionHandler {
    Logger log = LoggerFactory.getLogger(GuoDianMallExceptionHandler.class);

    @Override
    public ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
        ModelAndView mv = new ModelAndView();
        /*  使用FastJson提供的FastJsonJsonView视图返回,不需要捕获异常   */
        FastJsonJsonView view = new FastJsonJsonView();
        Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put("success", GuoDianMallConstant.FAILURE);
        String resultCode = exception instanceof VehsyRuntimeException ? ((VehsyRuntimeException) exception).getErrorCode() : GuoDianMallConstant.CODE_5001;
        attributes.put("resultCode", resultCode);
        attributes.put("resultMessage", getExceptionMsg(exception));
        view.setAttributesMap(attributes);
        mv.setView(view);
        log.warn("异常:" + exception.getMessage(), exception);
        return mv;
    }

    private String getExceptionMsg(Throwable t) {
        String exMsg = t.getMessage();
        Throwable tmp = t;
        while (StringUtils.isEmpty(exMsg) && (tmp = tmp.getCause()) != null){
            exMsg = tmp.getMessage();
        }
        if (StringUtils.isEmpty(exMsg)) {
            return t.getClass().toString();
        }
        return exMsg;
    }
}

-------使用fastjsonview-----------------

 

 

 

 

 

 

 

方式三:使用 @ControllerAdvice+ @ ExceptionHandler 注解

@ControllerAdvice
@ResponseBody
public class WebExceptionHandle {
    private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class);
    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("参数解析失败", e);
        return ServiceResponseHandle.failed("could_not_read_json");
    }
    
    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.error("不支持当前请求方法", e);
        return ServiceResponseHandle.failed("request_method_not_supported");
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) {
        logger.error("不支持当前媒体类型", e);
        return ServiceResponseHandle.failed("content_type_not_supported");
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public ServiceResponse handleException(Exception e) {
        if (e instanceof BusinessException){
            return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
        }
        
        logger.error("服务运行异常", e);
        e.printStackTrace();
        return ServiceResponseHandle.failed("server_error");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值