springmvc自定义异常处理器

这里就总结工作中用到的自定义异常处理器两类方式:
1 、实现HandlerExceptionResolver

定义两个异常类:业务异常(BusException)、空指针异常(NullException)继承自RuntimeException

package com.demo.exception;

/**
 * 业务异常
 * @author Administrator
 *
 */
public class BusException extends RuntimeException {

    /**错误码*/
    private String errorCode;


    public BusException(String errorCode) {
        this(errorCode, null, null);
    }

    public BusException(String errorCode, String message) {
        this(errorCode, message, null);
    }

    public BusException(String errorCode, Throwable cause) {
        this(errorCode, null, cause);
    }

    public BusException(String errorCode, String message, Throwable cause) {
        super(message, cause);

        this.errorCode = errorCode;
    }

    public String getErrorCode() {
        return errorCode;
    }

    @Override
    public String getMessage() {
        return super.getMessage();
    }


}
package com.demo.exception;
/**
 * 空指针异常
 * @author Administrator
 *
 */
public class NullException  extends RuntimeException{


    private String errorCode;


    public NullException(String errorCode) {
        this(errorCode, null, null);
    }

    public NullException(String errorCode, String message) {
        this(errorCode, message, null);
    }

    public NullException(String errorCode, Throwable cause) {
        this(errorCode, null, cause);
    }

    public NullException(String errorCode, String message, Throwable cause) {
        super(message, cause);

        this.errorCode = errorCode;
    }

    public String getErrorCode() {
        return errorCode;
    }

    @Override
    public String getMessage() {
        return super.getMessage();
    }
}

定义异常的常量code:

package com.demo.exception;

public class ErrorCodeConstants {


    public static final String NULL_ERROR = "01";
    public static final String BUSINESS_ERROR = "02";


}

定义异常的处理器:

package com.demo.exception;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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

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

import com.alibaba.fastjson.JSON;
import com.demo.exception2.BusinessException;
/**
 * 异常处理器
 * @author kxl
 *
 */
public class ErrorCodeExceptionHanler implements HandlerExceptionResolver {

    public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object obj,
            Exception ex) {
         ModelAndView mv = new ModelAndView(); 
         respJson(resp, ex);
         return mv;

    }
   //将异常信息写回
    void respJson(HttpServletResponse httpServletResponse, Exception ex)  {
        try {
            Map map = new HashMap<String, Object>();
            String errCode=null;
            String errMsg=ex.getMessage();
            if (ex instanceof NullException) {
                errCode=((NullException)ex).getErrorCode();
            }
            if (ex instanceof BusException) {
                errCode=((BusException)ex).getErrorCode();
            }
            map.put("errorCode", errCode);
            map.put("errorMsg", errMsg);
            httpServletResponse.addHeader("Content-Type", "application/json;chaset=UTF-8");
            httpServletResponse.getOutputStream().write(JSON.toJSONBytes(map));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

springmvc的配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.demo" />
    <mvc:annotation-driven>
    </mvc:annotation-driven>
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <!-- 全局异常处理 -->
    <bean id="handlerExceptionResolver" class="com.demo.exception.ErrorCodeExceptionHanler"/>
</beans>

测试的controller:

package com.demo.exception;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;



@RestController
public class TestController {
    @RequestMapping("/test")
    public String  test(@RequestParam Integer id){

        if (id==null) {
            throw new BusException(ErrorCodeConstants.NULL_ERROR,"参数为空");
        }
        if (id==0) {
            throw new BusException(ErrorCodeConstants.BUSINESS_ERROR,"业务异常");
        }
        return null;

    }

}

分别使用下面的测试url测试异常:
http://localhost:8087/test?id=0

响应:

{

    "errorCode": "02",
    "errorMsg": "业务异常"

}

http://localhost:8087/test?id=
响应:

{

    "errorCode": "01",
    "errorMsg": "参数为空"

}

2 、使用@ControllerAdvice@ExceptionHandler的全局异常处理器

定义3个异常类:业务异常(BussinessException)、数据库操作异常(DBException)、Http访问异常(HttpExcetpion)均继承自RuntimeException。

package com.demo.exception2;

/**
 *业务异常
*/
public class BusinessException extends RuntimeException {

    private String errCode;//错误码
    public BusinessException() {
        super();
    }

    public BusinessException(String errCode, Throwable cause) {
        super(cause);
        this.errCode = errCode;
    }

    public BusinessException(String errCode) {
        super();
        this.errCode = errCode;
    }

    public String getErrCode() {
        return errCode;
    }
}
package com.demo.exception2;
/**
 * 数据库操作异常
 * @author Administrator
 *
 */
public  class DBException extends RuntimeException {

    private String errCode;

    public DBException() {
        super();
    }

    public DBException(String errCode, Throwable cause) {
        super(cause);
        this.errCode = errCode;
    }

    public DBException(String errCode) {
        super();
        this.errCode = errCode;
    }

    public String getErrCode() {
        return errCode;
    }

}
package com.demo.exception2;
/**
 * http相关异常
 * @author Administrator
 *
 */
public  class HttpException extends RuntimeException {

    private String errCode;

    public HttpException() {
        super();
    }

    public HttpException(String errCode, Throwable cause) {
        super(cause);
        this.errCode = errCode;
    }

    public HttpException(String errCode) {
        super();
        this.errCode = errCode;
    }

    public String getErrCode() {
        return errCode;
    }

}

定义异常码类:

package com.demo.exception2;
/**
 * 异常码
 * @author Administrator
 *
 */
public class ErroCodeConstants {

    public  static String BS_0="0000";//业务异常1
    public  static String BS_1="0001";//业务异常2

    public  static String HTTP_403="403";//http 异常1
    public  static String HTTP_404="404";//http 异常2

    public  static String DB_0="2000"; //db操作异常1
    public  static String DB_1="2001"; //db操作异常2

}

定义异常国际化文件resultCode.properties:

0000=业务异常1
0000=业务异常2

403=http访问异常403
404=http访问异常404

2000=数据库操作异常1
2001=数据库操作异常2

定义通用异常返回体:

package com.demo.exception2;

public class GenericResp {
    // 请求的url
    private String reqUrl;
    // 错误码
    private String code;
    // 错误消息
    private String message;

    public GenericResp() {
        super();
    }

    public GenericResp(String reqUrl, String code, String message) {
        super();
        this.reqUrl = reqUrl;
        this.code = code;
        this.message = message;
    }

    public String getReqUrl() {
        return reqUrl;
    }

    public void setReqUrl(String reqUrl) {
        this.reqUrl = reqUrl;
    }

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

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

    public void setMessage(String message) {
        this.message = message;
    }

}

定义异常处理器:

package com.demo.exception2;


import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 自定义异常处理器
 * @author kxl
 *
 */

@ControllerAdvice
public class CustomExceptionHandler {


    @Autowired
    protected MessageSource messageSource;

    /**
     * 处理BusinessException
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public GenericResp handleBusinessException(HttpServletRequest request, BusinessException ex) {

        GenericResp resp = null;
        String url = request.getRequestURI();
        String code = ex.getErrCode();
        String msg = getExceptionMsg(code, ex, messageSource);;
        resp = new GenericResp(url, code,msg);
        return resp;
    }

    /**
     * 处理DBException
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(DBException.class)
    @ResponseBody
    public GenericResp handleDBException(HttpServletRequest request, DBException ex) {

        GenericResp resp = null;
        String url = request.getRequestURI();
        String code = ex.getErrCode();
        String msg = getExceptionMsg(code, ex, messageSource);;
        resp = new GenericResp(url, code,msg);
        return resp;
    }

    /**
     * 处理HttpException
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(HttpException.class)
    @ResponseBody
    public GenericResp HttpException(HttpServletRequest request, HttpException ex) {

        GenericResp resp = null;
        String url = request.getRequestURI();
        String code = ex.getErrCode();
        String msg = getExceptionMsg(code, ex, messageSource);;
        resp = new GenericResp(url, code,msg);
        return resp;
    }
    /**
     * 获取异常消息
     * @param code
     * @param ex
     * @param messageSource
     * @return
     */
    public static String getExceptionMsg(String code, Throwable ex, MessageSource messageSource) {
        String msg = "";
        try {
            msg = messageSource.getMessage(code, null, LocaleContextHolder.getLocale());
        }
        catch (NoSuchMessageException e) {
        }

        if (StringUtils.isEmpty(msg)) {
            msg=ex.getMessage();
        }
        return msg;
    }

}

springmvc配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.demo" />
    <mvc:annotation-driven>
    </mvc:annotation-driven>
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 消息处理i18n -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <value>i18n/resultCode</value>
        </property>
    </bean>
</beans>

测试controller:

package com.demo.exception2;

import java.math.BigDecimal;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;



@Controller
public class TestController2 {
    @ResponseBody
    @RequestMapping(value="/test2",produces=MediaType.APPLICATION_JSON_VALUE)
    public int  test(Integer id){

        if (id==null) {
            throw new BusinessException(ErroCodeConstants.BS_0);
        }
        if (id==0) {
            throw new BusinessException(ErroCodeConstants.BS_1);
        }

        if (id==403) {
            throw new HttpException(ErroCodeConstants.HTTP_403);
        }

        if (id==404) {
            throw new HttpException(ErroCodeConstants.HTTP_404);
        }

        if (id==2000) {
            throw new DBException(ErroCodeConstants.DB_0);
        }

        if (id==2001) {
            throw new DBException(ErroCodeConstants.DB_1);
        }
        return new Integer(1);
    }  
}

访问以下url测试异常:

业务异常测试:
http://localhost:8087/test2?id=
响应:

{

    "reqUrl": "/test2",
    "code": "0000",
    "message": "业务异常2"

}

http://localhost:8087/test2?id=0

{

    "reqUrl": "/test2",
    "code": "0001",
    "message": "业务异常2"

}

http异常测试:
http://localhost:8087/test2?id=403

{

    "reqUrl": "/test2",
    "code": "403",
    "message": "http访问异常403"

}

http://localhost:8087/test2?id=404

{

"reqUrl": "/test2",
"code": "404",
"message": "http访问异常404"

}

数据库异常测试:

http://localhost:8087/test2?id=2000

{

"reqUrl": "/test2",
"code": "2000",
"message": "数据库操作异常1"

}

http://localhost:8087/test2?id=2001

{

"reqUrl": "/test2",
"code": "2001",
"message": "数据库操作异常2"

}

猜你喜欢

转载自blog.csdn.net/u010248330/article/details/80761100