HandlerExceptionResolver统一异常处理 返回JSON 和 ModelAndView

统一异常处理类的两种方式一种是前后分离,一种是一整套集合返回指定到指定的错误页面显示错误信息

1.由于前后分离,是统一返回JSON的格式

自定义Exception

public class BussinessException extends RuntimeException {

    private static final long serialVersionUID = 1L;
    
    private int code;
    private String msg;
    
    public BussinessException(String msg) {
        super();
        this.msg = msg;
    }

    public BussinessException(int code, String msg) {
        super();
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    
}


  自定义统一异常处理类

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.bshf.recipe.exception.BussinessException;
import com.bshf.recipe.vo.basic.ResultVO;

/**
 * 异常处理类
 * 
 */
@Order(-1000)
public class ExceptionResolver implements HandlerExceptionResolver {

    private static Logger logger = LoggerFactory.getLogger("exceptionLog");
    
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        ResultVO result = new ResultVO();
        StringBuilder sb = new StringBuilder();
        
        //处理异常
        if(ex instanceof BussinessException) {
            resolverBussinessException(ex, sb, result);
        } else if (ex instanceof BindException) {
            resolverBindException(ex, sb, result);
        } else {
            resolverOtherException(ex, sb, result); 
        }
        
        result.setCode(0);
        result.setResult(sb);
        result.setTime(new Date());
        
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Cache-Control", "no-cache, must-revalidate");  
        try {
            response.getWriter().write(JSON.toJSONString(result));
        } catch (IOException e) {
            logger.error("与客户端通讯异常:" + e.getMessage(), e);
            e.printStackTrace();
        }
        
        logger.debug("异常:" + ex.getMessage(), ex);
        ex.printStackTrace();
        
        return new ModelAndView();
    }
    
    /*
     * 处理业务层异常 
     */
    private void resolverBussinessException(Exception ex, StringBuilder sb, ResultVO result) {
        BussinessException businessException = (BussinessException) ex;
        sb.append(businessException.getMsg());
        addResult(result, "业务异常");
    }
    
    /*
     * 处理参数绑定异常
     */
    private void resolverBindException(Exception ex, StringBuilder sb, ResultVO result) {
        BindException be = (BindException) ex;
        List<FieldError> errorList = be.getBindingResult().getFieldErrors();
        for (FieldError error : errorList) {
            sb.append(error.getObjectName());
            sb.append("对象的");
            sb.append(error.getField());
            sb.append("字段");
            sb.append(error.getDefaultMessage());
        }
        addResult(result, "参数传递异常");
    }
    
    /*
     * 处理其他异常
     */
    private void resolverOtherException(Exception ex, StringBuilder sb, ResultVO result) {
        sb.append(ex.getMessage());
        addResult(result, "其他异常");
    }

    /*
     * 封装code和msg
     */
    private void addResult(ResultVO result, String msg) {
        result.setMsg(msg);
    }
    
}

配置文件

<!-- 定义异常处理器 -->
<bean id="exceptionResolver" class="com.execption.ExceptionResolver"/>

 

运行流程分析
当你请求项目中某个接口时,如果报异常了,则会首先进入到这个自定义异常处理类中,然后通过判断异常类型来具体给客户端返回不同的信息提示。若接口没报异常,则此类的方法是不会运行的。

问:为什么要加@Order(-1000)
答:因为Spring默认有三个异常拦截器,里面的order属性分别为0,1,2,会首先去这三个拦截器中找匹配的异常,若有匹配的,则不会执行我们自定义的异常处理器。@Order(-1000)的作用就是将顺序提到第一位,先加载我们的,有符合异常条件的,则不会继续走其他三个默认的。(我们这里一定会走,因为首先是order变成了-1000,其次是我们对自定义异常、BindException和其他做了捕获,所以一定不会执行Spring默认的)

问:为什么在最后添加了ex.printStackTrace();
答:一切为了调试方便,这样可以将异常信息打印到控制台,方便查看。

问:为什么要判断BindException?
答:一切为了调试方便。他会配合javax.validation.*中的注解一起用,比如客户端传入的参数加上了如下

@NotNull(message = "id不能为空")
private Integer id;
@NotEmpty(message = "title不能为空或空字符串")
private String title;

 

这时候我调用接口如果id和title都不传的话会进入我们的自定义异常处理类中去捕获,异常类型为BindException,会返回给客户端如下json:

{
    "code": 0,
    "msg": "参数传递异常",
    "result": "demoIO对象的title字段title不能为空或空字符串demoIO对象的id字段id不能为空",
    "time": 1491551183087
}

 

这样就完成了统一异常处理。若没报异常则不会执行此方法,报异常则将异常信息返回给客户端方便调试。

2.后台管理同意处理返回到指定的错误页面方式
/**
 * 
* 类名称:MyExceptionResolver.java
* 类描述: 

* @version 1.0
 */
public class MyExceptionResolver implements HandlerExceptionResolver{
    protected Logger logger = Logger.getLogger(this.getClass());
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        // TODO Auto-generated method stub
        System.out.println("==============异常开始=============");
        System.out.println("request.getRemoteAddr():"+request.getRemoteAddr());
        System.out.println("request.getMethod():"+request.getMethod());
        System.out.println("request.getQueryString():"+request.getQueryString());
        //logger.error("ex.getCause().getMessage():"+ex.getCause().getMessage());
        logger.error("request.getRequestURL():"+request.getRequestURL());
        //ex.printStackTrace();
        System.out.println("==============异常结束=============");
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception", ex.toString().replaceAll("\n", "<br/>"));

        return mv;
    }

}

 

转载于:https://www.cnblogs.com/zuolun2017/p/8046263.html

Java中实现统一异常处理可以通过以下步骤进行操作: 1. 创建一个全局异常处理类:创建一个类,用于处理应用程序中抛出的所有异常。可以命名为GlobalExceptionHandler或类似的名称。 ```java public class GlobalExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 在这里处理异常返回适当的错误响应 return new ModelAndView("error"); // 返回一个自定义的错误页面或其他错误响应 } } ``` 2. 实现HandlerExceptionResolver接口:让全局异常处理类实现HandlerExceptionResolver接口,并实现其中的resolveException()方法。 3. 处理异常返回错误响应:在resolveException()方法中,根据需要对捕获到的异常进行适当的处理,并返回一个错误响应给客户端。可以是一个自定义的错误页面,或者是一个包含错误信息的JSON对象。 4. 注册全局异常处理器:将全局异常处理器注册到应用程序中,以确保它能够捕获到所有的异常。具体的注册方式取决于所使用的Java框架。 在Spring框架中,可以通过以下方式注册全局异常处理器: ```java @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { resolvers.add(new GlobalExceptionHandler()); } } ``` 在Spring Boot框架中,可以通过以下方式注册全局异常处理器: ```java @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleException(Exception ex) { // 在这里处理异常返回适当的错误响应 ErrorResponse errorResponse = new ErrorResponse("500", "Internal Server Error"); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } } ``` 需要根据具体的需求框架进行调整实施。以上是一种常见的实现方式,可以根据自己的需求进行扩展定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值