Skip to content

自定义异常过滤器

一、背景

系统开发过程中存在,存在不可预知的异常。当这些异常被捕获的时候,如果没有进行一个统一的处理,会返回到前端,暴露异常信息。这时候需要设置全局的异常捕获,如果出现异常按照规定的返回格式, 返回前端固定的json信息。还有一些自定义的异常类的处理,比如实体类的属性上加@NotBlank(message = "提示信息")。如果不进行处理,在controller判断的时候, 会直接返回异常的报错信息。需要自定义处理

二、实现方式

多的不说,上代码

自定义异常类:


/**
 * @Description 自定义ServiceException异常
 * @Author lcy
 * @Date 2020/12/7 14:20
 */
public class ServiceException extends RuntimeException {

    /**
     * 响应码
     */
    @Getter
    @Setter
    private String code;

    public ServiceException(String message){
        super(message);
        this.code = "601";
    }

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

    public ServiceException(ResultCode resultCode){
        super(resultCode.getMessage());
        this.code = resultCode.getCode();
    }

}

返回结果类:


/**
 * @Description 响应信息主体,返回的报文信息类
 * @Author lcy
 * @Date 2020/4/10 14:23
 */
@ApiModel(description = "默认返回结果对象")
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Accessors(chain = true)
@Data
public class Result<T> implements Serializable {

    /**
     * 响应状态
     */
    @ApiModelProperty(value = "响应状态", required = true)
    protected boolean success;

    /**
     * 响应码
     */
    @ApiModelProperty(value = "响应码", required = true)
    protected String code;

    /**
     * 响应消息
     */
    @ApiModelProperty(value = "响应消息", required = true)
    protected String message;

    /**
     * 响应数据
     */
    @ApiModelProperty(value = "响应数据")
    protected T data;

    public Result(ResultCode resultCode){
        this.success = resultCode.isSuccess();
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }

    public Result(ResultCode resultCode,T data){
        this.success = resultCode.isSuccess();
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
        this.data = data;
    }

    /**
     * 创建返回消息对象
     *
     * @param code    响应码
     * @param message 返回提示
     * @return com.lcy.base.common.response.Result<Object>
     * @author lcy
     * @date 2020/12/7 14:32
     **/
    public static <T> Result<T> create(String code,String message){
        return Result.<T>builder().success("200".equals(code)).code(code).message(message).build();
    }

    /**
     * 创建返回消息对象
     *
     * @param code    响应码
     * @param message 返回提示
     * @param data    响应数据
     * @return com.lcy.base.common.response.Result<T>
     * @author lcy
     * @date 2020/12/7 14:38
     **/
    public static <T> Result<T> create(String code,String message,T data){
        return Result.<T>builder().success("200".equals(code)).code(code).message(message).data(data).build();
    }

    /**
     * 创建返回消息对象
     *
     * @param resultCode 枚举对象
     * @return com.lcy.base.common.response.Result<T>
     * @author lcy
     * @date 2020/12/7 14:38
     **/
    public static <T> Result<T> create(ResultCode resultCode){
        return Result.<T>builder().success(resultCode.isSuccess()).code(resultCode.getCode()).message(resultCode.getMessage()).build();
    }

    /**
     * 创建返回消息对象
     *
     * @param resultCode 枚举对象
     * @param data       数据集合
     * @return com.lcy.base.common.response.Result<T>
     * @author lcy
     * @date 2020/12/7 14:38
     **/
    public static <T> Result<T> create(ResultCode resultCode,T data){
        return Result.<T>builder().success(resultCode.isSuccess()).code(resultCode.getCode())
                .message(resultCode.getMessage()).data(data).build();
    }

    /**
     * 创建返回消息对象
     *
     * @param data 返回数据
     * @return com.lcy.base.common.response.Result<T>
     * @author lcy
     * @date 2020/12/7 14:38
     **/
    public static <T> Result<T> create(T data){
        return Result.<T>builder().success(CommonCode.SUCCESS.isSuccess()).code(CommonCode.SUCCESS.getCode())
                .message(CommonCode.SUCCESS.getMessage()).data(data).build();
    }

    /**
     * 返回成功的消息对象
     *
     * @return com.lcy.base.common.response.Result<Object>
     * @author lcy
     * @date 2020/12/7 14:55
     **/
    public static <T> Result<T> success(){
        return create(CommonCode.SUCCESS);
    }

    /**
     * 返回带数据的成功消息对象
     *
     * @return com.lcy.project.entity.response.Result<T>
     * @author lcy
     * @date 2020/4/10 16:15
     **/
    public static <T> Result<T> success(T data){
        return create(data);
    }

    /**
     * 返回成功的消息对象
     *
     * @return com.lcy.base.common.response.Result<Object>
     * @author lcy
     * @date 2020/12/7 14:55
     **/
    public static <T> Result<T> failed(String message){
        return Result.<T>builder().success(false).code("601").message(message).build();
    }

    /**
     * 返回系统异常的信息
     *
     * @return com.lcy.base.common.response.Result
     * @author lcy
     * @date 2020/4/10 16:16
     **/
    public static <T> Result<T> exception(){
        return create(CommonCode.SERVER_EXCEPTION);
    }

    /**
     * 返回系统错误的信息
     *
     * @return com.lcy.base.common.response.Result
     * @author lcy
     * @date 2020/4/10 16:16
     **/
    public static <T> Result<T> error(){
        return create(CommonCode.SERVER_EXCEPTION);
    }

}

异常处理类:

/**
 * @Description 异常捕获--只捕获web.controller下的异常,对内部接口的异常不捕获
 * @Author lcy
 * @Date 2020/12/7 14:18
 */
@RestControllerAdvice(basePackages = "**.web.controller")
public class GlobalExceptionHandler {

    /**
     * Exception异常
     *
     * @param request   请求对象
     * @param exception 异常信息
     * @author lcy
     * @date 2019/10/26 9:44
     **/
    @ExceptionHandler({Exception.class})
    public Result<Object> exception(HttpServletRequest request,Exception exception){
        Log.error("system error! requestURI:{} ",request.getRequestURI(),exception);
        return Result.exception();
    }

    /**
     * 自定义业务异常
     *
     * @param request          请求对象
     * @param serviceException 异常信息
     * @author lcy
     * @date 2019/10/26 9:44
     **/
    @ExceptionHandler({ServiceException.class})
    public Result<Object> serviceException(HttpServletRequest request,ServiceException serviceException){
        Log.error("ServiceException requestURI:{},message:{} ",request.getRequestURI(),serviceException.getMessage());
        return Result.create(serviceException.getCode(),serviceException.getMessage());
    }

    /**
     * 参数校验异常
     *
     * @param request       请求对象
     * @param bindException 异常信息
     * @author lcy
     * @date 2019/10/26 9:44
     **/
    @ExceptionHandler({BindException.class,MethodArgumentNotValidException.class,ConstraintViolationException.class})
    public Result<Object> bindException(HttpServletRequest request,BindException bindException){
        Log.error("param BindException!requestURI:{} ",request.getRequestURI(),bindException);

        StringBuilder stringBuilder = new StringBuilder();

        //获取所有的错误参数提示
        bindException.getBindingResult().getFieldErrors()
                .forEach(fieldError -> stringBuilder.append(fieldError.getDefaultMessage()).append(","));

        //如果有错误提示,去除最后的逗号。
        if (stringBuilder.length() > 0) {
            stringBuilder.setLength(stringBuilder.length() - 1);
        } else {
            stringBuilder.append("传入参数异常!");
        }

        return Result.failed(stringBuilder.toString());
    }

}