SpringBoot Build Global Exception Interception

  • 2021-10-13 07:31:53
  • OfStack

Directory 2. controller Test 3. Start springboot Project 4. Test 5. Global Exception System 1 Handling Based on Springboot itself 6. AOP can also implement global handling of exceptions

1. Creation of exception interception classes


package com.liqi.web.core.exception;
 
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
 
import com.liqi.common.base.Constants;
import com.liqi.common.base.ResultBean;
import com.liqi.common.exception.BusinessInterfaceException;
import com.liqi.common.exception.bean.ErrorBean;
 
import lombok.extern.slf4j.Slf4j;
 
/**
 *  Custom exception handler 
 *
 * @author ieflex
 */
@RestControllerAdvice
@Slf4j
public class InterfaceExceptionHandler {
 
	/**
	 *  Interface   Business exception 
	 */
	@ResponseBody
	@ExceptionHandler(BusinessInterfaceException.class)
	public String businessInterfaceException(BusinessInterfaceException e) {
		log.error(e.getMessage(), e);
		ErrorBean error = e.getError();
		ResultBean resultBean = new ResultBean(error.hashCode(), error.getErrorMsg());
		return resultBean.toString();
	}
 
	/**
	 *  Intercept all runtime global exceptions    
	 */
	@ExceptionHandler(RuntimeException.class)
	@ResponseBody
	public String runtimeException(RuntimeException e) {
		log.error(e.getMessage(), e);
		//  Return  JOSN
		ResultBean resultBean = new ResultBean(Constants.INTERFACE_MSG_301, Constants.INTERFACE_MSG_301_TEXT);
		return resultBean.toString();
	}
 
	/**
	 *  System exception capture processing 
	 */
	@ExceptionHandler(Exception.class)
	@ResponseBody
	public String exception(Exception e) {
		log.error(e.getMessage(), e);
		ResultBean resultBean = new ResultBean(Constants.INTERFACE_MSG_301, Constants.INTERFACE_MSG_301_TEXT);
		//  Return  JOSN
		return resultBean.toString();
	}
}

2. controller test


package com.springboot_Error.ErrorController;
        
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        
        @Controller
        public class ErrorControllerTest {
            // Global exception interception   Test 
            @RequestMapping("/ErrorTest")
            public String index2(){
                System.err.println(" Request succeeded! ");
                int i = 1/0; // There will be 1 Operation exceptions 
                return "index";
            }
            
        }

3. Start the springboot project


package com.springboot_Error.ErrorRun;
        
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
 
        
        // Scanning  com.springboot_Error.ErrorController  Under the package  controller  Annotated class 
        @ComponentScan(basePackages={"com.springboot_Error.ErrorController"})
        @EnableAutoConfiguration
        public class ErrorRun {
            
            public static void main(String[] args) {
                SpringApplication.run(ErrorRun.class, args);
            }
            
        }

STEP 4 Test


/**
 *  Functional description :  Simulate custom exceptions 
 * @return
 */
@RequestMapping(value = "/api/test")  
public Object myext() {
    throw new BusinessInterfaceException("500", "my ext Anomaly ");
}

After testing, it is found that the exceptions of Controller layer can be caught. The current premise is that Controller layer does not handle the exceptions catch. If Controller layer handles the exceptions catch, the exceptions of Controller layer will not be caught here, so pay attention to this one point.

5. Global exception system 1 handling based on Springboot itself

It mainly implements ErrorController interface or inherits AbstractErrorController abstract class or inherits BasicErrorController class

The following is an example code given by a blogger on the Internet. The blog address is: https://blog.csdn.net/king_is_everyone/article/details/53080851


 
@Controller
@RequestMapping(value = "error")
@EnableConfigurationProperties({ServerProperties.class})
public class ExceptionController implements ErrorController {
 
    private ErrorAttributes errorAttributes;
 
    @Autowired
    private ServerProperties serverProperties;
 
 
    /**
     *  Initialization ExceptionController
     * @param errorAttributes
     */
    @Autowired
    public ExceptionController(ErrorAttributes errorAttributes) {
        Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
        this.errorAttributes = errorAttributes;
    }
 
 
    /**
     *  Definition 404 Adj. ModelAndView
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(produces = "text/html",value = "404")
    public ModelAndView errorHtml404(HttpServletRequest request,
                                  HttpServletResponse response) {
        response.setStatus(getStatus(request).value());
        Map<String, Object> model = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.TEXT_HTML));
        return new ModelAndView("error/404", model);
    }
 
    /**
     *  Definition 404 Adj. JSON Data 
     * @param request
     * @return
     */
    @RequestMapping(value = "404")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error404(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.TEXT_HTML));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);
    }
 
    /**
     *  Definition 500 Adj. ModelAndView
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(produces = "text/html",value = "500")
    public ModelAndView errorHtml500(HttpServletRequest request,
                                  HttpServletResponse response) {
        response.setStatus(getStatus(request).value());
        Map<String, Object> model = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.TEXT_HTML));
        return new ModelAndView("error/500", model);
    }
 
 
    /**
     *  Definition 500 Errors of JSON Information 
     * @param request
     * @return
     */
    @RequestMapping(value = "500")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error500(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.TEXT_HTML));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);
    }
 
 
    /**
     * Determine if the stacktrace attribute should be included.
     * @param request the source request
     * @param produces the media type produced (or {@code MediaType.ALL})
     * @return if the stacktrace attribute should be included
     */
    protected boolean isIncludeStackTrace(HttpServletRequest request,
                                          MediaType produces) {
        ErrorProperties.IncludeStacktrace include = this.serverProperties.getError().getIncludeStacktrace();
        if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {
            return true;
        }
        if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {
            return getTraceParameter(request);
        }
        return false;
    }
 
 
    /**
     *  Get the wrong information 
     * @param request
     * @param includeStackTrace
     * @return
     */
    private Map<String, Object> getErrorAttributes(HttpServletRequest request,
                                                   boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(request);
        return this.errorAttributes.getErrorAttributes(requestAttributes,
                includeStackTrace);
    }
 
    /**
     *  Whether to include trace
     * @param request
     * @return
     */
    private boolean getTraceParameter(HttpServletRequest request) {
        String parameter = request.getParameter("trace");
        if (parameter == null) {
            return false;
        }
        return !"false".equals(parameter.toLowerCase());
    }
 
    /**
     *  Get error code 
     * @param request
     * @return
     */
    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request
                .getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        try {
            return HttpStatus.valueOf(statusCode);
        }
        catch (Exception ex) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }
 
    /**
     *  Implement error path , Temporarily useless 
     * @see ExceptionMvcAutoConfiguration#containerCustomizer()
     * @return
     */
    @Override
    public String getErrorPath() {
        return "";
    }
 
}

6. AOP can also implement global handling of exceptions


@Component
@Aspect
public class ExceptionAspectController {
    public static final Logger logger = LoggerFactory.getLogger(ExceptionAspectController.class);
 
    @Pointcut("execution(* com.test.test.*.*(..))")// Here, make specific settings based on the path of your own project 
    public void pointCut(){}
 
    @Around("pointCut()")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) {
        Stopwatch stopwatch = Stopwatch.createStarted();
 
        APIResponse<?> apiResponse;
        try {
            logger.info(" Execute Controller Begin : " + pjp.getSignature() + "  Parameters: " + Lists.newArrayList(pjp.getArgs()).toString());
            apiResponse = (APIResponse<?>) pjp.proceed(pjp.getArgs());
            logger.info(" Execute Controller End : " + pjp.getSignature() + " ,   Return value: " + apiResponse.toString());
            logger.info(" Time consuming: " + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "( Milliseconds ).");
        } catch (Throwable throwable) {
            apiResponse = handlerException(pjp, throwable);
        }
 
        return apiResponse;
    }
 
    private APIResponse<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
        APIResponse<?> apiResponse = null;
        if(e.getClass().isAssignableFrom(MessageCenterException.class) ){
            MessageCenterException messageCenterException = (MessageCenterException)e;
            logger.error("RuntimeException{ Methods: " + pjp.getSignature() + " ,   Parameters: " + pjp.getArgs() + ", Exception: " + messageCenterException.getException().getMessage() + "}", e);
            apiResponse = messageCenterException.getApiResponse();
        } else if (e instanceof RuntimeException) {
            logger.error("RuntimeException{ Methods: " + pjp.getSignature() + " ,   Parameters: " + pjp.getArgs() + ", Exception: " + e.getMessage() + "}", e);
            apiResponse = new APIResponse(APIResponse.FAIL,null,e.getMessage());
        } else {
            logger.error(" Anomaly { Methods: " + pjp.getSignature() + " ,   Parameters: " + pjp.getArgs() + ", Exception: " + e.getMessage() + "}", e);
            apiResponse = new APIResponse(APIResponse.FAIL,null,e.getMessage());
        }
 
        return apiResponse;
    }
}

Related articles: