`
Luob.
  • 浏览: 1589875 次
  • 来自: 上海
社区版块
存档分类
最新评论

SpringMVC 统一异常处理

 
阅读更多
先说说 网上流传的几种处理方式:
方式1:使用SimpleMappingExceptionResolver实现异常处理  (试验过, 对于表单请求异常 和ajax 请求异常处理不方便) 实验的结果就是判断 如果出现404 500错误,判断不出来源是ajax 还是 普通页面请求  所以放弃了
package cn.mwee.wpos.report.cache;

import cn.mwee.utils.error.ThrowableUtil;
import cn.mwee.wpos.report.consts.ResultCode;
import cn.mwee.wpos.service.conts.ErrorCode;
import cn.mwee.wpos.service.conts.ErrorDesc;
import cn.mwee.wpos.service.dto.common.ErrorResult;
import com.alibaba.fastjson.JSON;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

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


/**
 * Created by luob on 2017/6/27.
 */
public class GlobalExceptionResolver extends SimpleMappingExceptionResolver {
   @Override
   protected ModelAndView doResolveException(HttpServletRequest request,
                          HttpServletResponse response, Object handler, Exception ex){
             String viewName = determineViewName(ex,request);
             response.setCharacterEncoding("UTF-8");

             String requestType = request.getHeader("X-Requested-With");
             if (viewName != null) {// JSP格式返回
                 if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
                         .getHeader("X-Requested-With") != null && 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格式返回
                             try {
                                     PrintWriter writer = response.getWriter();
                                     Map<String,Object>  result=new HashMap<>();
                                     ErrorResult error=new ErrorResult(ErrorCode.FAIL, ErrorDesc.FAIL, ThrowableUtil.getStackTrace(ex));
                                     result.put(ResultCode.ERROR,error);
                                     writer.write(JSON.toJSONString(result));
                                     writer.flush();
                                     writer.close();
                                 } catch (IOException e) {
                                     e.printStackTrace();
                                 }
                             return null;
                         }
             } else{
                 return null;
             }
         }
    
}


方法二:@ExceptionHandler + @ControllerAdvice
问题是:可以正确获取 所有的异常 ,但是request 和response 获取不到 异常后 应该返回的 status 比如 404  500 415
package cn.mwee.wpos.report.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
@Slf4j
public class ErrorHandlerController {

    @ExceptionHandler(value = Exception.class)
    public String exception(HttpServletRequest request, Exception ex) {
        log.info("ErrorHandlerController.exception");
        request.setAttribute("httpStatus", Integer.toString(getHttpStatus(ex).value()));
        request.setAttribute("httpMessage", getHttpStatus(ex).getReasonPhrase());
        request.setAttribute("errorType", ex.getClass().getName());
        request.setAttribute("errorMessage", ex.getMessage());
        request.setAttribute("errorStackTrace", ExceptionUtils.getStackTrace(ex));
       //必须是 forward 否则 /error 区分不了 ajax 和普通的请求
        return "forward:/error";
    }

    public HttpStatus getHttpStatus(Exception ex) {
        if (ex instanceof org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException) {
            return HttpStatus.NOT_FOUND;
        } else if (ex instanceof HttpRequestMethodNotSupportedException) {
            return HttpStatus.METHOD_NOT_ALLOWED;
        } else if (ex instanceof HttpMediaTypeNotSupportedException) {
            return HttpStatus.UNSUPPORTED_MEDIA_TYPE;
        } else if (ex instanceof HttpMediaTypeNotAcceptableException) {
            return HttpStatus.NOT_ACCEPTABLE;
        } else if (ex instanceof MissingPathVariableException) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        } else if (ex instanceof MissingServletRequestParameterException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof ServletRequestBindingException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof ConversionNotSupportedException) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        } else if (ex instanceof TypeMismatchException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof HttpMessageNotReadableException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof HttpMessageNotWritableException) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        } else if (ex instanceof MethodArgumentNotValidException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof MissingServletRequestPartException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof BindException) {
            return HttpStatus.BAD_REQUEST;
        } else if (ex instanceof NoHandlerFoundException) {
            return HttpStatus.NOT_FOUND;
        } else if (ex instanceof AsyncRequestTimeoutException) {
            return HttpStatus.SERVICE_UNAVAILABLE;
        } else {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }
}


方法3: web.xml + controller 来实现
web.xml 中配置
    <!--error page-->
    <error-page>
        <location>/error</location>
    </error-page>

package cn.mwee.wpos.report.controller.error;

import cn.mwee.utils.error.ThrowableUtil;
import cn.mwee.utils.log4j2.LogData;
import cn.mwee.utils.uuid.UUIDUtil;
import cn.mwee.wpos.common.utils.AlfredCommonUtils;
import cn.mwee.wpos.report.consts.ResultCode;
import cn.mwee.wpos.service.conts.ErrorCode;
import cn.mwee.wpos.service.conts.ErrorDesc;
import cn.mwee.wpos.service.dto.common.ErrorResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.util.WebUtils;

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

@Controller
public class ErrorController {
    /**
     * 异常页面
     * @param ex
     * @param response
     * @return
     */
    @RequestMapping(path = "/error")
    public ModelAndView errorHtml(HttpServletRequest request,Exception ex,HttpServletResponse response) {
        int status=response.getStatus();
        ModelAndView modelAndView;
        if(status == 403 || status == 404 || status == 500) {
            modelAndView = new ModelAndView("error/" +status);
        }else{
            modelAndView = new ModelAndView("error/error");
        }
        modelAndView.addObject("status",status);
        return modelAndView;
    }

    /**
     * 异常json
     * @param ex
     * @param response
     * @return
     */
    @RequestMapping(path = "/error",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Map<String, Object> errorJson(HttpServletRequest request,Exception ex,HttpServletResponse response) {
        Map<String,Object> result=new HashMap<>();
        Object obj=request.getAttribute(DispatcherServlet.EXCEPTION_ATTRIBUTE);
        if(obj == null){
            obj=request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE);
        }
        if(obj !=null && obj instanceof Exception){
            ex=(Exception)obj;
        }
        ErrorResult error=new ErrorResult(ErrorCode.FAIL, ErrorDesc.FAIL, ThrowableUtil.getStackTrace(ex));
        result.put(ResultCode.ERROR,error);
        return result;
    }

}



分享到:
评论

相关推荐

    springMVC统一异常处理.mp4

    本视频针对博客内容,讲解springMVC框架中的统一异常处理的知识点和实例,以及500错误和404错误异常处理上的区别,简单易懂,言简意赅。

    SpringMVC统一异常处理实例代码

    SpringMVC统一异常处理实例代码 本文主要介绍了SpringMVC统一异常处理实例代码,通过示例代码详细介绍了统一异常处理的方法,对大家的学习或者工作具有一定的参考学习价值。 在项目中,异常处理是一个非常重要的...

    SpringMVC统一异常处理三种方法详解

    这篇文章主要介绍了SpringMVC-统一异常处理三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在 Spring MVC 应用的开发中,不管是对底层数据库操作...

    Maven+SpringMVC实现统一异常处理

    总结,通过Maven和SpringMVC的结合,我们可以构建一个高效的统一异常处理系统,提高代码的可维护性和用户体验。在实际开发中,还可以根据项目需求进行更复杂的异常分类和处理策略,以满足不同场景下的需求。

    spingmvc+mybatis+统一异常处理机制

    统一异常处理会区分前端是否ajax请求,自动返回json数据格式,要求开发人员在处理ajax请求时统一封装成一个对象返回,以符合代码统一规范。 此工程在idea环境编写,导入请自己新建工程手工复制代码导入。

    spring+springmvc+mybatis项目案例实现用户角色权限管理

    使用了springmvc统一异常处理 使用了FormattingConversionServiceFactoryBean对于传入参数中日期或数字字符串进行数据转换和数据格式化 使用了SpringContextHolder方便在自定义线程中调用spring已经实例的bean,如...

    springmvc返回json的全局异常统一处理demo

    springmvc返回json的全局异常统一处理demo,有问题可以留言。

    springmvc 异常统一处理的三种方式详解.docx

    在Spring MVC框架中,异常处理是一项关键任务,它确保了应用程序在遇到错误或异常时能够以优雅的方式响应,提供统一的错误信息,并保持代码的整洁和模块化。本篇文章将详细探讨Spring MVC处理异常的三种主要方法:...

    三. spring mvc 异常统一处理

    NULL 博文链接:https://gaojiewyh.iteye.com/blog/1297746

    SpringMVC 中的拦截器与异常处理

    在SpringMVC中,异常处理可以帮助我们优雅地管理可能出现的错误情况,提供统一的错误页面和反馈。 1. 声明式异常处理:可以通过在控制器方法上使用`@ExceptionHandler`注解来指定特定异常的处理逻辑。这种方法适用...

    Springboot全局异常处理demo.zip

    Springboot全局异常处理demo 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免...使用统一异常处理的好处是能够将异常信息统一捕捉并组装成固定格式的数据返回。

    SpringMVC异常处理知识点总结

    在 Spring MVC 框架中,统一异常处理是通过使用 @ControllerAdvice 注解来实现的。@ControllerAdvice 注解用于标记一个类,以便它可以从控制器中捕捉异常。使用 @ControllerAdvice 注解的类可以捕捉所有控制器中的...

    使用Spring MVC统一异常处理实战

    NULL 博文链接:https://cgs1999.iteye.com/blog/1547197

    完整版 Java开发实训课程系列-SpringMVC框架技术教程 第6章 异常处理 (共12页).pptx

    **SpringMVC框架中的异常处理**是Java开发中不可或缺的一部分,它确保了应用程序在遇到错误时能够优雅地处理并提供有用的反馈。在SpringMVC框架中,异常处理机制允许开发者集中处理可能出现的各种异常,提高代码的可...

    SSM后台整合(Spring+SpringMvc+Mybtis+事务+Rest风格+统一结果封装+统一异常处理+拦截器)

    SSM后台整合(Spring+SpringMvc+Mybtis+事务+Rest风格+统一结果封装+统一异常处理+拦截器) 适合新手练习,熟悉ssm框架 也适合需要进行ssm框架开发的同学,直接无需搭建框架,拿来即用哦

    使用Spring进行统一日志管理 + 统一异常管理

    1. 便于维护程序的日志记录和异常处理 2. 降低程序的复杂性,提高程序的可读性和可维护性 3. 提高程序的鲁棒性,减少程序的错误率 4. 便于开发者追踪程序的执行过程,Debug 程序错误 结论 使用 Spring 进行统一日...

    springmvc+mybatis核心类包括登录校验验证码统一异常处理多种接口与父类

    异常统一处理类SysExceptionReslver 用户登录校验过滤器LoginFilter 自定义拦截器SysInterceptor 验证码图片生成CheckCodeServlet 分组校验器ValidGroupSave和ValidGroupUpdate 另外还有IBaseMapper、IBaseService、...

    详解Spring MVC/Boot 统一异常处理最佳实践

    Spring MVC/Boot 统一异常处理最佳实践 本文将详细介绍 Spring MVC/Boot 统一异常处理的最佳实践,讨论如何在 Web 开发中处理各种异常,总结了一些常见的异常处理反例,并提供了一个统一的异常处理规范。 异常...

Global site tag (gtag.js) - Google Analytics