springMVC 统一异常处理 返回JSON数据

需求

在后台开发中,难免会存在一些异常,如果我们在controller中一个一个的去try catch处理,会很繁琐,并且不好维护;如果在web.xml配置错误页面,会导致返回一个试图给前台,对于前后端分离的不太友好,前台无法解析,这明显不是我们想要的,我们需要的是返回串JSON的错误码给前台;

@ControllerAdvice

从spring3.2开始,增加了新注解@ControllerAdvice,控制器增强的注解。其原理是使用AOP对Controller控制器进行增强(前置增强、后置增强、环绕增强,AOP原理请自行查阅);这样我们就可以自行对控制器的方法进行调用前(前置增强)和调用后(后置增强)的处理。

如果要返回JSON格式,只需要创建一个ExceptionHandler的class 用@ControllerAdvice注解,里面通过@ExceptionHandler来注解了的方法处理数据,处理中将Exception转换为Json格式返回即可。

代码

package com.XXX.XXX

import com.XXXX.common.GenericResponse;
import com.XXXX.common.ServiceError;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;


/**
 * 招生统一异常处理
 */
@ControllerAdvice
public class XXXXExceptionHandler {

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

    /**
     * 运行时异常
     * @param runtimeException
     * @return 
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public GenericResponse runtimeExceptionHandler(RuntimeException runtimeException) {
        logger.error(runtimeException.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"系统运行异常");
    }

    /**
     * 空指针异常
     * @param ex
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public GenericResponse nullPointerExceptionHandler(NullPointerException ex) {
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"系统空指针异常");
    }


    /*----- REQUEST ERROR -----*/

    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public GenericResponse requestNotReadable(HttpMessageNotReadableException ex){
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"参数格式错误(缺少分隔符或结束标签)");
    }

    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public GenericResponse requestTypeMismatch(TypeMismatchException ex){
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"参数类型不匹配");
    }

    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public GenericResponse requestMissingServletRequest(MissingServletRequestParameterException ex){
        logger.error(ex.getMessage());
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"缺少请求参数");
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public GenericResponse request405(){
        return GenericResponse.response(ServiceError.UN_KNOW_ERROR,"不支持该请求方式");
    }

}

说明

  1. 需要注意的是该类一定要存放到能够被spring扫描到的地方
  2. 其中GenericResponse 及 ServiceError是自定义的响应结果,可修改为自己定义的(因为各自的项目的响应结果都不一样,这边就不贴出来了)
  3. @ExceptionHandler表示需要处理的异常类型
  4. @ResponseStatus表示修改返回的http状态
  5. @ResponseBody表示返回JSON、因为GenericResponse为一个实体对象,所以最终将对象转为JSON再返回给前台

效果图

后台controller抛出异常,无需try catch
springMVC 统一异常处理 返回JSON数据_第1张图片

你可能感兴趣的:(Java,spring)