SpringBoot 2 整合aop实现日志和全局异常处理

698 阅读3分钟

1. Exceptions

介绍

@Controller and @ControllerAdvice classes can have @ExceptionHandler methods to handle exceptions from controller methods, as the following example shows:

@RestControllerAdvice
public class GlobalException {

    @ExceptionHandler(Exception.class)
    public String handlerRuntimeException(RuntimeException ex, HttpServletRequest req, HttpServletResponse resp) {
        String uri = req.getRequestURI();
        String errorMsg = ex.getMessage();
        System.out.println("uri: " + uri + "\nerror: " + errorMsg);
        return "uri: " + uri + "\nerror: " + errorMsg;
    }
}

1.2 @ExceptionHandler 注解下的函数支持的参数

Method argumentDescription
Exception typeFor access to the raised exception.
HandlerMethodFor access to the controller method that raised the exception.
WebRequestNativeWebRequestGeneric access to request parameters and request and session attributes without direct use of the Servlet API.
javax.servlet.ServletRequestjavax.servlet.ServletResponseChoose any specific request or response type (for example, ServletRequest or HttpServletRequest or Spring’s MultipartRequest or MultipartHttpServletRequest).
javax.servlet.http.HttpSessionEnforces the presence of a session. As a consequence, such an argument is never null. Note that session access is not thread-safe. Consider setting the RequestMappingHandlerAdapter instance’s synchronizeOnSession flag to true if multiple requests are allowed to access a session concurrently.
java.security.PrincipalCurrently authenticated user — possibly a specific Principal implementation class if known.
HttpMethodThe HTTP method of the request.
java.util.LocaleThe current request locale, determined by the most specific LocaleResolver available — in effect, the configured LocaleResolver or LocaleContextResolver.
java.util.TimeZonejava.time.ZoneIdThe time zone associated with the current request, as determined by a LocaleContextResolver.
java.io.OutputStreamjava.io.WriterFor access to the raw response body, as exposed by the Servlet API.
java.util.Maporg.springframework.ui.Modelorg.springframework.ui.ModelMapFor access to the model for an error response. Always empty.
RedirectAttributesSpecify attributes to use in case of a redirect — (that is to be appended to the query string) and flash attributes to be stored temporarily until the request after the redirect. See Redirect Attributes and Flash Attributes.
@SessionAttributeFor access to any session attribute, in contrast to model attributes stored in the session as a result of a class-level @SessionAttributes declaration. See @SessionAttribute for more details.
@RequestAttributeFor access to request attributes. See @RequestAttribute for more details.

1.3 @ExceptionHandler 注解下的函数支持的返回值

Return valueDescription
@ResponseBodyThe return value is converted through HttpMessageConverter instances and written to the response. See @ResponseBody.
HttpEntity<B>ResponseEntity<B>The return value specifies that the full response (including the HTTP headers and the body) be converted through HttpMessageConverter instances and written to the response. See ResponseEntity.
StringA view name to be resolved with ViewResolver implementations and used together with the implicit model — determined through command objects and @ModelAttribute methods. The handler method can also programmatically enrich the model by declaring a Model argument (described earlier).
ViewView instance to use for rendering together with the implicit model — determined through command objects and @ModelAttribute methods. The handler method may also programmatically enrich the model by declaring a Model argument (descried earlier).
java.util.Maporg.springframework.ui.ModelAttributes to be added to the implicit model with the view name implicitly determined through a RequestToViewNameTranslator.
@ModelAttributeAn attribute to be added to the model with the view name implicitly determined through a RequestToViewNameTranslator.Note that @ModelAttribute is optional. See “Any other return value” at the end of this table.
ModelAndView objectThe view and model attributes to use and, optionally, a response status.
voidA method with a void return type (or null return value) is considered to have fully handled the response if it also has a ServletResponse an OutputStream argument, or a @ResponseStatus annotation. The same is also true if the controller has made a positive ETag or lastModified timestamp check (see Controllers for details).If none of the above is true, a void return type can also indicate “no response body” for REST controllers or default view name selection for HTML controllers.
Any other return valueIf a return value is not matched to any of the above and is not a simple type (as determined by BeanUtils#isSimpleProperty), by default, it is treated as a model attribute to be added to the model. If it is a simple type, it remains unresolved.

assignableTypes 可指定ControllerAdvice只作用于哪些Controller类

@RestControllerAdvice(assignableTypes = {MyController.class, UserController.class})

2. 错误打印日志 配置 Slf4j

2.1 application.yml 配置


logging:
  level:
    com.kenny: debug
  file:
    path: my-log/myLog //打印日志存放路径

2.2 在想要输出日志的文件添加LOGGER

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestControllerAdvice
public class GlobalException {
    // declare 变量并将该.class文件作为参数传送给LoggerFactory
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalException.class);

    @ExceptionHandler(Exception.class)
    public String handlerRuntimeException(HandlerMethod method, Exception ex, HttpServletRequest req, HttpServletResponse resp) {
        String uri = req.getRequestURI();
        String errorMsg = ex.getMessage();
        System.out.println("method name:  " + method.getMethod().getName());
        System.out.println("uri: " + uri + "\nerror: " + errorMsg);
        //此处打印日志,并会自动将日志输出到指定的日志文件
        LOGGER.info("用户访问:{},报错:{}" + "  uri: " + uri + "\nerror: " + errorMsg);
        return "uri: " + uri + "\nerror: " + errorMsg;
    }
}