当前位置:网站首页>Chapter 8: custom exception return
Chapter 8: custom exception return
2022-07-22 21:04:00 【Bug Hu Hansan】
In the process of running the program , No one can guarantee that we can be 100% free BUG、 No abnormal . When the program breaks an exception , We often need to intercept , Special friendly prompt processing .
So here we will focus on Spring Mvc Follow Spring Security Do some interception for exceptions of .
@RestControllerAdvice
We use Spring mvc after , Just add... To the class @RestControllerAdvice annotation , You can return most of the exceptions of the program to the client for processing
import com.hzw.code.common.utils.ActionException;
import com.hzw.code.common.utils.ActionResult;
import com.hzw.code.common.utils.ResultCodeEnum;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import java.util.List;
/**
* Global exception handling
*
* @author: Hu Hansan
* @date: 2020/5/26 12:00
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
private ActionResult commonHandleException(Exception e){
if(e instanceof ActionException) {
Object result = ((ActionException) e).getResult();
if (result instanceof ActionResult) {
ActionResult actionResult =(ActionResult) result;
return commonHandleException(actionResult.getCode(), actionResult.getMessage());
} else {
return commonHandleException(ResultCodeEnum.ERROR_DEFAULT, getRealExceptionMessage(e));
}
}else{
return commonHandleException(ResultCodeEnum.ERROR_DEFAULT, getRealExceptionMessage(e));
}
}
private ActionResult commonHandleException(ResultCodeEnum resultCode, String errorMsg){
log.error(errorMsg);
return commonHandleException(resultCode.getValue(), errorMsg);
}
private ActionResult commonHandleException(Integer resultCode, String errorMsg) {
return new ActionResult(resultCode, errorMsg, null);
}
/**
* loop exception Of cause, Get the real error message
* @param exception
* @return
*/
public String getRealExceptionMessage(Exception exception){
// Initialize to top-level exception message
String message = exception.getMessage();
if(StringUtils.isBlank(message)
|| message.indexOf("Exception") == -1){
message = exception.toString();
}
Throwable e = exception.getCause();
// Prevent entering too many cycles , Cycle at most 10 Layer anomaly
for(int i = 0;i < 10;i++){
if(e == null){
break;
}
message = e.getMessage();
if(StringUtils.isBlank(message)
|| message.indexOf("Exception") == -1){
message = e.toString();
}
e = e.getCause();
}
return message;
}
@ExceptionHandler(ActionException.class)
public ActionResult<Object> handleActionExecption(ActionException exception) {
return commonHandleException(exception);
}
/**
* Check error interception processing
*
* @param exception Error message set
* @return error message
*/
@ExceptionHandler({BindException.class, MethodArgumentNotValidException.class})
public ActionResult<Object> validationBodyException(Exception exception){
BindingResult bindResult = null;
if (exception instanceof BindException) {
bindResult = ((BindException) exception).getBindingResult();
} else if (exception instanceof MethodArgumentNotValidException) {
bindResult = ((MethodArgumentNotValidException) exception).getBindingResult();
}
StringBuffer sb = new StringBuffer();
if (bindResult.hasErrors()) {
List<ObjectError> errors = bindResult.getAllErrors();
if(errors != null && errors.size() > 0){
errors.forEach(p ->{
FieldError fieldError = (FieldError) p;
log.error(" Data validation failed : object{"+fieldError.getObjectName()+"},field{"+fieldError.getField()+
"},errorMessage{"+fieldError.getDefaultMessage()+"}");
if(sb.toString().indexOf(fieldError.getDefaultMessage()) == -1){
sb.append(fieldError.getDefaultMessage() + ",");
}
});
}
}
String msg = sb.toString();
if(msg.length() > 1){
msg = msg.substring(0, msg.length()-1);
}
return commonHandleException(ResultCodeEnum.DATA_INPUT_ERROR, msg);
}
/**
* Parameter type conversion exception handling
* @param exception
* @return
*/
@ExceptionHandler(HttpMessageConversionException.class)
public ActionResult<Object> parameterTypeException(HttpMessageConversionException exception){
return commonHandleException(ResultCodeEnum.DATA_INPUT_TYPE_ERROR, getRealExceptionMessage(exception));
}
/**
* Controller Input parameter format conversion error exception handling
* @param exception
* @return
*/
@ExceptionHandler({ HttpMessageNotReadableException.class })
public ActionResult<Object> handleHttpMessageNotReadableException(HttpMessageNotReadableException exception) {
return commonHandleException(ResultCodeEnum.DATA_INPUT_ERROR, getRealExceptionMessage(exception));
}
/**
* The request method does not support exception handling
* @param exception
* @return
*/
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
public ActionResult<Object> handleMethodNotSupportedException(Exception exception) {
return commonHandleException(ResultCodeEnum.ERROR_HTTP_METHOD, getRealExceptionMessage(exception));
}
/**
* Type conversion error
* @param exception
* @return
*/
@ExceptionHandler({MethodArgumentTypeMismatchException.class})
public ActionResult<Object> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException exception) {
return commonHandleException(ResultCodeEnum.DATA_INPUT_TYPE_ERROR, getRealExceptionMessage(exception));
}
/**
* Global program exception handling class
* @param exception
* @return
*/
@ExceptionHandler({ Exception.class, RuntimeException.class })
public ActionResult<Object> handleException(Exception exception) {
exception.printStackTrace();
return commonHandleException(exception);
}
/**
* jwt Exception handling class
* @param exception
* @return
*/
@ExceptionHandler({ ExpiredJwtException.class })
public ActionResult<Object> handleExpiredJwtException(ExpiredJwtException exception) {
exception.printStackTrace();
return commonHandleException(exception);
}
}
And after , Let's access some methods where we throw exceptions manually
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/admin/auth")
public Object adminAuth(){
throw new ActionException(" Abnormal abnormal ");
// return "ROLE_ADMIN jurisdiction !";
}
Deliberately input wrong token
Here you can see , The return of this exception is not in our unified return format at all , That is to say, we didn't deal with this . We also added ExpiredJwtException Treatment method . But it didn't work .
ErrorController
Some exceptions thrown in the program are not detected by the above @RestControllerAdvice Handle . therefore @RestControllerAdvice Not all exceptions returned by the program can be handled . So we are using ErrorController To process
import com.hzw.code.common.utils.ActionResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Objects;
/**
* spring security exception handling
*
* @author: Hu Hansan
* @date: 2020/5/26 12:00
*/
@Slf4j
@RestController
public class CustomErrorController implements ErrorController {
private static final String PATH = "/error";
@Autowired
private ErrorAttributes errorAttributes;
@RequestMapping(value = PATH)
ActionResult error(HttpServletRequest request, HttpServletResponse response) {
// Appropriate HTTP response code (e.g. 404 or 500) is automatically set by Spring.
// Here we just define response body.
Map<String, Object> errorMap = getErrorAttributes(request);
// Define the return format
ActionResult d = new ActionResult();
d.setSuccess(false);
d.setMessage(Objects.requireNonNull(errorMap.get("message")).toString());
d.setCode(Integer.valueOf(Objects.requireNonNull(errorMap.get("status")).toString()));
d.setData(errorMap.get("error"));
response.setStatus(HttpServletResponse.SC_OK);
return d;
}
@Override
public String getErrorPath() {
return PATH;
}
/**
* Get request parameters
* @param request
* @return
*/
private Map<String, Object> getErrorAttributes(HttpServletRequest request) {
WebRequest requestAttributes = new ServletWebRequest(request);
return errorAttributes.getErrorAttributes(requestAttributes,false);
}
}
Let's test
And after , We intercepted this exception .
----------------------------------------------------------
Source address of the project :https://gitee.com/gzsjd/fast
----------------------------------------------------------
边栏推荐
猜你喜欢
第四章:minio的presigned URLs上传文件
Install pycharm
微信小程序Cannot read property 'setData' of null错误
BUUCTF闯关日记03--[极客大挑战 2019]Havefun1
Redis series 14 -- redis cluster
Pytest testing framework built quickly
Write a 3D banner using JS
Set colSpan invalidation for TD of table
Using MySQL database in Django
JMeter performance test
随机推荐
Mysql 导入3亿数据
ThreadLocal encountered data problems in thread pool and Solutions
MATLAB2017a环境下使用libsvm-3.23出现的问题与解决方案
Bash基本功能—历史命令与补全
Multithread 01 -- create thread and thread state
BUUCTF闯关日记--[SUCTF 2019]CheckIn1()
Buuctf entry diary -- [mrctf2020] how about you (super detailed)
BUUCTF闯关日记02--[HCTF 2018]WarmUp1
RPM包管理—YUM在线管理-IP地址配置和网络YUM源
Multithreading 03 -- synchronized and lock escalation
测试相关基础概念
第六章:easyCode代码生成器
第七章:使用jwt token的方式来进行登录
Bash变量--位置参数变量
Airtest conducts webui automated testing (selenium)
BUUCTF闯关日记--[MRCTF2020]Ezpop1
人类群星网站收集计划--Michael Kerrisk
流程控制.
微信小程序Cannot read property 'setData' of null錯誤
JMeter performance test