springmvc的异常处理

1、 为什么需要异常处理?

  在软件开发过程中,往往会出现一些不可预知的错误,这些错误有可能花费你数小时甚至数天的时间。异常处理通常是防止这种未知错误的常用措施,它的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。 

 

2、springmvc的异常处理

  

package com.roton.app.controller.resolver;

import com.roton.app.bean.ResponseVo;
import com.roton.app.bean.StatusCode;
import com.roton.app.exception.RotonException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class ExceptionResolverCustom implements HandlerExceptionResolver {


    // json转换器
    // 将异常信息转json
   
    private HttpMessageConverter jsonMessageConverter;

    private static final Logger logger = LoggerFactory.getLogger(ExceptionResolverCustom.class);

    // 前端控制器调用此方法执行异常处理
    // handler,执行的action类就包装了一个方法(对应url的方法)
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response, Object handler, Exception ex) {

        logger.error(   ex.getMessage()   );
        // 输出 异常信息
        // 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法)
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 取出方法
        Object obj = handlerMethod.getBean();
        Method method = handlerMethod.getMethod();

        //TODO   更具方法的返回值去定义返回
        Type[] paramTypeList = method.getGenericParameterTypes();// 方法的参数列表
        // 判断方法是否返回json
        // 只要方法上有responsebody注解表示返回json
        // 查询method是否有responsebody注解
        RestController rest = AnnotationUtils.findAnnotation(obj.getClass(), RestController.class);
        ResponseBody responseBody = AnnotationUtils.findAnnotation(method,
                ResponseBody.class);
        if (responseBody != null || rest != null) {
            // 将异常信息转json输出
            return this.resolveJsonException(request, response, handlerMethod, ex);
        }
        // 这里说明action返回的是jsp页面
        // 解析异常
        RotonException appException = resolveExceptionCustom(ex);
        // 将异常信息在异常页面显示
        // 转向错误页面
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("exception",
                appException.getMessage());
        modelAndView.addObject("url",
                request.getRequestURI());

        if (appException.getMessage().contains("权限")){
            modelAndView.setViewName("/401");// 逻辑视图名
        }else {
            modelAndView.setViewName("/error");// 逻辑视图名
        }
        return modelAndView;
    }


    // 异常信息解析方法
    private RotonException resolveExceptionCustom(Exception ex) {
        RotonException resultInfo = null;
        if (ex instanceof RotonException) {
            // 抛出的是系统自定义异常
            resultInfo = (RotonException) ex;
        } else {
            //  AppException(String statusCode, String message) {
            // 重新构造“未知错误”异常
            resultInfo = new RotonException(StatusCode.FAILED, "未知错误!");
        }
        return resultInfo;
    }


    // 将异常信息转json输出
    private ModelAndView resolveJsonException(HttpServletRequest request,
                                              HttpServletResponse response, Object handler, Exception ex) {
        // 解析异常
        RotonException appException = resolveExceptionCustom(ex);
        HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
        try {
            //将AppException对象转成json输出
            //boolean status, String statusCode, String message
            ResponseVo responseVo = new ResponseVo(false, StatusCode.FAILED, appException.getMessage());
            jsonMessageConverter.write(responseVo, MediaType.APPLICATION_JSON, outputMessage);
        } catch (HttpMessageNotWritableException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ModelAndView();
    }


    public HttpMessageConverter<ResponseVo> getJsonMessageConverter() {
        return jsonMessageConverter;
    }


    public void setJsonMessageConverter(
            HttpMessageConverter<ResponseVo> jsonMessageConverter) {
        this.jsonMessageConverter = jsonMessageConverter;
    }


}
原文地址:https://www.cnblogs.com/scholar-xie/p/6992549.html