自定义异常过滤器
一、背景
系统开发过程中存在,存在不可预知的异常。当这些异常被捕获的时候,如果没有进行一个统一的处理,会返回到前端,暴露异常信息。这时候需要设置全局的异常捕获,如果出现异常按照规定的返回格式, 返回前端固定的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());
}
}