SpringMVC下全局异常统一响应返回JSON及自定义异常

Spring MVC框架下一般会自定义全局异常,再通过Spring MVC下的全局异常拦截全部转化为自定义异常。但在controller层处理异常有很多的try{}catch{},影响性能。所以为了能够处理异常的同时返回相同的数据结构,定义一个全局异常统一响应以返回JSON格式数据结构(code:“”,message:“”,data:“”)。

1.自定义异常类(继承RuntimeException以保证事务可以回滚):

package exception;

/**
 * 自定义异常
 */
public class MyException extends RuntimeException{
    private static final long serialVersionUID = 2305653807231756702L;
    //异常信息
    private String message;
    //构造器
    public MyException(String message){
        super(message);
        this.message=message;
    }
    @Override
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }

}

 

2.自定义拦截全局异常处理器(以保证可以拦截框架下的所有异常)

package exception;

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

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

public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        MyException myException = null;
        if (e instanceof MyException) {
            myException = (MyException) e;
        } else {//如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
            myException = new MyException("未知错误");
        }
        return null;
    }
}

3.配置全局异常处理器(springmvc-servlet.xml)

<!--自定义的全局异常处理器-->
<bean id="myHandlerExceptionResolver" class="exception.MyHandlerExceptionResolver"/>

4.自定义全局异常响应(以保证controller层抛出的异常能够全局响应JSON)

package exception;

import model.ResponseData;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;


/**
 * @ControllerAdvice是一个@Component,用于定义@ExceptionHandler
 *
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public ResponseData jsonExceptionHandler(HttpServletRequest request, MyException e) {
        return new ResponseData().fail(e.getMessage());
    }

}

其中的ResponseData类如下:

package model;

import java.util.LinkedHashMap;

/**
 * 用来返回controller层请求的结果
 * 默认为三个返回项:code,message,data
 * 如果有其他更多返回项,使用result方法拼接
 */
public class ResponseData extends LinkedHashMap<String, Object> {

    private static final long serialVersionUID = -364546270975223015L;

    public ResponseData result(String key, Object value) {
        this.put(key, value);
        return this;
    }

    public ResponseData success(){
        return this.success("success");
    }
    public ResponseData success(Object message){
        this.put("code",200);
        this.put("message", message);
        return this;
    }

    public ResponseData fail(){
        return this.fail("fail");
    }

    public ResponseData fail(Object message) {
        this.put("code",400);
        this.put("message", message);
        return this;
    }

    public ResponseData redirect(String message) {
        this.put("code",300);
        this.put("message", message);
        return this;
    }

    public ResponseData unauthorized() {
        return this.unauthorized("the current user is unauthorized");
    }
    public ResponseData unauthorized(Object message){
        this.put("code",401);
        this.put("message", message);
        return this;
    }

    public ResponseData forbidden(Object message){
        this.put("code",403);
        this.put("message", message);
        return this;
    }

    public ResponseData code(int code) {
        return result("code",code);
    }

    public ResponseData message(String message) {
        return result("message", message);
    }

    public ResponseData data(Object data) {
        return result("data", data);
    }
}

5.配置全局异常统一响应处理器

在springmvc-servlet.xml中:

<!--配置全局异常统一响应处理器-->
<context:component-scan base-package="exception" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

在web.xml中:

<!--2.配置 Spring MVC DispatcherServlet 前端控制器 -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置全局异常统一响应处理器,DispatcherServlet源码中对于throwExceptionIfNoHandlerFound 默认是 false -->
    <init-param>
        <param-name>throwExceptionIfNoHandlerFound</param-name>
        <param-value>true</param-value>
    </init-param>
    <!-- contextConfigLocation 是参数名称,该参数的值包含 Spring MVC 的配置文件路径 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 在 Web 应用启动时立即加载 Servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>

6.效果如下:

controller层不用再进行try{}catch{},直接抛出异常即可

返回示例:

至此就不用在controller层每次进行try{}catch{}了。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值