6. Handle exceptions in a unified way and record logs in a unified way using the idea of AOP

#Unified exception handling

SpringBoot has a unified method of handling exceptions

To put the exception under a specific path, you only need to put the error page under templates/error. The name of the error page should be consistent with the error type code

When the corresponding type error occurs, springboot will automatically jump to the corresponding page.

Spring handles exception logging

After logging, you need to manually jump to the server error page

@RequestMapping(value = "/error",method = RequestMethod.GET)
public String getErrorPage()
{
    return "/error/500";
}

Spring handles Controller requests

There is no need to process a Controller, and all Controller requests can be processed

//Scan methods containing Controller annotations
@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {
    //Instantiation log
    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    //This method will be called after an exception occurs in the Controller to catch the exception and record the log
    //Pass in the request and response objects. It is used to obtain the request method and return information
    @ExceptionHandler({Exception.class})
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //Information of traversing exception stack
        logger.error("Server exception: " + e.getMessage());
        for (StackTraceElement element : e.getStackTrace()) {
            logger.error(element.toString());
        }

        //Determine whether the browser requests a page or an asynchronous request returns a JSON string
        //Fixed skills are obtained through reques ts
        String xRequestedWith = request.getHeader("x-requested-with");
        if ("XMLHttpRequest".equals(xRequestedWith)) {
            //The response returns a normal string
            response.setContentType("application/plain;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(CommunityUtil.getJSONString(1, "Server exception!"));
        } else {
            response.sendRedirect(request.getContextPath() + "/error");
        }
    }
}

Unified logging

AOP terminology

  • Target: the goal of processing requirements;
  • Aspect encapsulates the components of business requirements;
  • Use the framework to weave Aspect into the requirements to be processed;
  • Weaving in during compilation, the program runs efficiently, but some errors may be caused by insufficient conditions; Low weaving efficiency during operation
  • The position of JoinPoint woven into the requirement target (attribute, method);
  • Pointcut expression declaration, which declares the position of the woven object;
  • Advice specific logic and execution location

Implementation of AOP

• AspectJ (a new language with powerful functions)

-AspectJ is a language level implementation that extends the Java language and defines AOP syntax.

-AspectJ weaves code during compilation. It has a special compiler to generate class files that comply with Java bytecode specifications.

• Spring AOP (mostly weaving methods)

-Spring AOP is implemented in pure Java. It does not require a special compilation process or a special class loader.

-Spring AOP weaves code through proxy at runtime, and only supports connection points of method types.

-Spring supports the integration of AspectJ.

Spring AOP

Proxy: the object generates a proxy object. When calling, the proxy object is called instead of the original object, and the code is woven into the proxy object

• JDK dynamic agent (the target needs to have an interface)

-The dynamic proxy technology provided by Java can create the proxy instance of the interface at runtime.

-Spring AOP adopts this method by default, weaving code into the proxy instance of the interface.

• CGLib dynamic agent

-Use the underlying bytecode technology to create subclass proxy instances at runtime.

-When the target object does not have an interface, Spring AOP will weave code into the subclass instance in this way.

Spring AOP application and five types of notifications

– first set all parameters of pointcut expression execution + return type (*) + pointcut object path + object method + (...)

 @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")

  public void pointcut() {

  }

//1. Start execution at connection point
 @Before("pointcut()")
//2. Execute after the connection point returns
 @AfterReturning("pointcut()")
//3. Execute after connection point
 @After("pointcut()")
//4. Execute after the connection point throws an exception
 @AfterThrowing("pointcut()")

//5. Before and after the connection point
//ProceedingJoinPoint joinPoint is the connection point
//joinPoint.proceed();   Call the original object method
  @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around before");
        Object obj = joinPoint.proceed();
        System.out.println("around after");
        return obj;
    }

Unified logging

@Component
@Aspect
public class ServiceLogAspect {
    private static final Logger logger= LoggerFactory.getLogger(ServiceLogAspect.class);

    //Declared tangent point
    @Pointcut("execution(* com.js.community.service.*.*(..))")
    public void pointcut()
    {

    }

    //At the connection point, the method is executed by the actuator
    @Before("pointcut()")
    public void before(JoinPoint joinPoint)
    {
        // The user [1.2.3.4] visited [com.js.community.service.xxx()] on [xxx]
        //Get user ip through request tool class
        ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String IP = request.getRemoteHost();
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        logger.info(String.format("user[%s],stay[%s],Visited[%s].", IP, now, target));


    }
}

DEBUG

@Aspect cannot find the annotation import dependency

<!--AOP Dependent package-->
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>

Keywords: Java Spring Spring Boot data structure Back-end

Added by ialsoagree on Wed, 02 Mar 2022 10:49:47 +0200