package
com.bsj.obd.config.exception;
import com.bsj.consumerQ.Until.ExceptionUntil;
import com.bsj.obd.global.JsonResult;
import com.bsj.obd.global.JsonResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
*
*/
@Slf4j
@RestControllerAdvice
@Order(-1)
public class GlobalExceptionHandler {
private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: requestUrl: %s Code: %s Detail: %s";
/**
* 参数校验返回
*
* @param ex
* @return
* @throws Exception
*/
@ExceptionHandler(value = BindException.class)
public JsonResult bindExceptionErrorHandler(BindException ex) {
log.error("bindExceptionErrorHandler info:{}", ex.getMessage());
StringBuilder sb = new StringBuilder();
FieldError fieldError = ex.getFieldError();
sb.append(fieldError.getDefaultMessage());
return new JsonResult(JsonResultEnum.PARAM_ERROR.getCode(), sb.toString());
}
/**
* 自定义异常返回
*
* @param apiException
* @return
*/
@ExceptionHandler(ApiException.class)
public JsonResult handFaceException(ApiException apiException) {
JsonResultEnum status = apiException.getStatus();
return new JsonResult(status, apiException.getMessage());
}
/**
* 其他错误
*
* @param ex
* @return
*/
@ExceptionHandler({Exception.class})
public JsonResult exception(HttpServletRequest request, Exception ex) {
return resultFormat(request, JsonResultEnum.EXCEPTION, ex);
}
/**
* 运行时异常
*
* @param ex
* @return
*/
@ExceptionHandler(RuntimeException.class)
public JsonResult runtimeExceptionHandler(HttpServletRequest request, RuntimeException ex) {
return resultFormat(request, JsonResultEnum.RUNTIME_EXCEPTION, ex);
}
/**
* 空指针异常
*
* @param ex
* @return
*/
@ExceptionHandler(NullPointerException.class)
public JsonResult nullPointerExceptionHandler(HttpServletRequest request, NullPointerException ex) {
return resultFormat(request, JsonResultEnum.NPE, ex);
}
/**
* 类型转换异常
*
* @param ex
* @return
*/
@ExceptionHandler(ClassCastException.class)
public JsonResult classCastExceptionHandler(HttpServletRequest request, ClassCastException ex) {
return resultFormat(request, JsonResultEnum.CLASS_CAST_EXCEPTION, ex);
}
/**
* IO异常
*
* @param ex
* @return
*/
@ExceptionHandler(IOException.class)
public JsonResult iOExceptionHandler(HttpServletRequest request, IOException ex) {
return resultFormat(request, JsonResultEnum.IO_EXCEPTION, ex);
}
/**
* 未知方法异常
*
* @param ex
* @return
*/
@ExceptionHandler(NoSuchMethodException.class)
public JsonResult noSuchMethodExceptionHandler(HttpServletRequest request, NoSuchMethodException ex) {
return resultFormat(request, JsonResultEnum.NO_SUCH_METHOD_EXCEPTION, ex);
}
/**
* 数组越界异常
*
* @param ex
* @return
*/
@ExceptionHandler(IndexOutOfBoundsException.class)
public JsonResult indexOutOfBoundsExceptionHandler(HttpServletRequest request, IndexOutOfBoundsException ex) {
return resultFormat(request, JsonResultEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION, ex);
}
/**
* 400错误
*
* @param ex
* @return
*/
@ExceptionHandler({HttpMessageNotReadableException.class})
public JsonResult requestNotReadable(HttpServletRequest request, HttpMessageNotReadableException ex) {
System.out.println("400..requestNotReadable");
return resultFormat(request, JsonResultEnum.HTTP_MESSAGE_NOT_READABLE_EXCEPTION, ex);
}
/**
* 400错误
*
* @param ex
* @return
*/
@ExceptionHandler({TypeMismatchException.class})
public JsonResult requestTypeMismatch(HttpServletRequest request, TypeMismatchException ex) {
System.out.println("400..TypeMismatchException");
return resultFormat(request, JsonResultEnum.Type_MISMATCH_EXCEPTION, ex);
}
/**
* 400错误
*
* @param ex
* @return
*/
@ExceptionHandler({MissingServletRequestParameterException.class})
public JsonResult requestMissingServletRequest(HttpServletRequest request, MissingServletRequestParameterException ex) {
System.out.println("400..MissingServletRequest");
return resultFormat(request, JsonResultEnum.MISSING_SERVLET_REQUEST_PARAMETER_EXCEPTION, ex);
}
/**
* 405错误
*
* @param ex
* @return
*/
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
public JsonResult request405(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) {
return resultFormat(request, JsonResultEnum.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION, ex);
}
/**
* 500错误
*
* @param ex
* @return
*/
@ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
public JsonResult server500(HttpServletRequest request, RuntimeException ex) {
System.out.println("500...");
return resultFormat(request, JsonResultEnum.FAIL_SERVER, ex);
}
/**
* 栈溢出
*
* @param ex
* @return
*/
@ExceptionHandler({StackOverflowError.class})
public JsonResult requestStackOverflow(HttpServletRequest request, StackOverflowError ex) {
return resultFormat(request, JsonResultEnum.SOE, ex);
}
private <T extends Throwable> JsonResult resultFormat(HttpServletRequest request, JsonResultEnum jsonResultEnum, T ex) {
ex.printStackTrace();
log.error("@@@服务异常" + String.format(logExceptionFormat, request.getRequestURL(), jsonResultEnum, ExceptionUntil.getErrorStr(ex)));
return new JsonResult(JsonResultEnum.EXCEPTION);
}
}
package com.bsj.obd.config.exception;
import com.bsj.obd.global.JsonResultEnum;
public class ApiException extends RuntimeException {
//利用枚举来统一规范返回语句,利于后期的海外版扩展
//public enum JsonResultEnum {
//
// SUCCESS(0, "请求成功"),
// FAIL(-1, "请求失败"),
// PARAM_ERROR(-2, "参数错误"),
//;
// private Integer code;
// private String msg;
//
// JsonResultEnum(Integer code, String message) {
// this.code = code;
// this.msg = message;
// }
//
// public Integer getCode() {
// return code;
// }
//
// public String getMsg() {
// return msg;
// }
//
// public void setMsg(String msg) {
// this.msg = msg;
// }
//}
// private JsonResultEnum status;
//
//
// public ApiException(JsonResultEnum status) {
// this.status = status;
// }
public ApiException(JsonResultEnum status, String message) {
super(message);
// Assert.notNull(message, "message cant't be null");
// 自定义异常提示
// public static void main(String[] args) {
// getaVoid();
// System.out.println("hello");
// }
//
// private static void getaVoid() {
// Assert.notNull(null, "Source must not be null");
// }
// Assert.notNull(status, "status cant't be null");
status.setMsg(message);
this.status = status;
}
public ApiException(JsonResultEnum status, String message, Throwable cause) {
super(message, cause);
// Assert.notNull(message, "message cant't be null");
// Assert.notNull(status, "status cant't be null");
this.status = status;
}
//这个才是自定义的正则返回,方法在全局异常拦截哪里
public JsonResultEnum getStatus() {
return status;
}
}
确定之一就是:如果只单单返回String的话是会报转换类型错误,因为String不是基本类型,List就可以转换成功
package com.bsj.obd.config.advice;
import com.bsj.obd.global.JsonResult;
import com.bsj.obd.global.PageJsonResult;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 统一修改api的成功返回值
*/
//表示在com.bsj.obd.web这个包里面的所有返回都进行修改
@RestControllerAdvice(basePackages = {"com.bsj.obd.web"})
public class ApiControllerAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (!(body instanceof JsonResult) && !(body instanceof PageJsonResult)) {
return JsonResult.success(body);
}
return body;
}
}