详解AOP与Filter拦截请求打印日志实用例子

作者:EalenXie 时间:2021-09-26 22:03:10 

相信各位同道在写代码的时候,肯定会写一些日志打印,因为这对往后的运维而言,至关重要的。

那么我们请求一个restfull接口的时候,哪些信息是应该被日志记录的呢?

以下做了一个基本的简单例子,这里只是示例说明基本常规实现记录的信息,根据项目的真实情况选用:

1 . Http请求 * (Filter) : 从HttpServletRequest获取基本的请求信息


import name.ealen.util.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Created by EalenXie on 2018/9/7 15:56.
* Http请求 * ,日志打印请求基本相关信息
*/
@Configuration
public class FilterConfiguration {

private static final Logger log = LoggerFactory.getLogger(FilterConfig.class);

@Bean
 @Order(Integer.MIN_VALUE)
 @Qualifier("filterRegistration")
 public FilterRegistrationBean filterRegistration() {
   FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
   registration.setFilter(controllerFilter());
   registration.addUrlPatterns("/*");
   return registration;
 }

private Filter controllerFilter() {
   return new Filter() {
     @Override
     public void init(FilterConfig filterConfig) {
       log.info("ControllerFilter init Success");
     }

@Override
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
       HttpServletRequest request = (HttpServletRequest) servletRequest;
       HttpServletResponse response = (HttpServletResponse) servletResponse;
       String requestId = request.getHeader("Request-Id");
       if (requestId == null) requestId = request.getRequestedSessionId();
       System.out.println();
       log.info("Http Request Request-Id : " + requestId);
       log.info("Http Request Information : {\"URI\":\"" + request.getRequestURL() +
           "\",\"RequestMethod\":\"" + request.getMethod() +
           "\",\"ClientIp\":\"" + HttpUtil.getIpAddress(request) +
           "\",\"Content-Type\":\"" + request.getContentType() +
           "\"}");
       chain.doFilter(request, response);
     }

@Override
     public void destroy() {
       log.info("ControllerFilter destroy");
     }
   };
 }
}

2 . Controller的拦截AOP : 获取 请求的对象,请求参数,返回数据,请求返回状态,内部方法耗时。


import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
* Created by EalenXie on 2018/9/7 14:19.
* AOP打印日志 : 请求的对象,请求参数,返回数据,请求状态,内部方法耗时
*/
@Aspect
@Component
public class ControllerInterceptor {

private static final Logger log = LoggerFactory.getLogger(ControllerInterceptor.class);
 @Resource
 private Environment environment;

@Around(value = "execution (* name.ealen.web.*.*(..))")
 public Object processApiFacade(ProceedingJoinPoint pjp) {
   String appName;
   try {
     appName = environment.getProperty("spring.application.name").toUpperCase();
   } catch (Exception e) {
     appName = "UNNAMED";
   }
   long startTime = System.currentTimeMillis();
   String name = pjp.getTarget().getClass().getSimpleName();
   String method = pjp.getSignature().getName();
   Object result = null;
   HttpStatus status = null;
   try {
     result = pjp.proceed();
     log.info("RequestTarget : " + appName + "." + name + "." + method);
     log.info("RequestParam : " + JSON.toJSON(pjp.getArgs()));
     if (result instanceof ResponseEntity) {
       status = ((ResponseEntity) result).getStatusCode();
     } else {
       status = HttpStatus.OK;
     }
   } catch (Throwable throwable) {
     status = HttpStatus.INTERNAL_SERVER_ERROR;
     result = new ResponseEntity<>("{\"Internal Server Error\" : \"" + throwable.getMessage() + "\"}", status);
     throwable.printStackTrace();
   } finally {
     log.info("ResponseEntity : {" + "\"HttpStatus\":\"" + status.toString() + "\"" + ",\"ResponseBody\": " + JSON.toJSON(result) + "}");
     log.info("Internal Method Cost Time: {}ms", System.currentTimeMillis() - startTime);
   }
   return result;
 }
}

3 . 提供一个简单的restfull接口 :


package name.ealen.web;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* Created by EalenXie on 2018/9/7 14:24.
*/
@RestController
public class SayHelloController {

@RequestMapping("/sayHello")
 public String sayHello() {
   return "hello world";
 }

@RequestMapping("/say")
 public ResponseEntity<?> say(@RequestBody Object o) {
   return new ResponseEntity<>(o, HttpStatus.OK);
 }

}

4 . 使用Postman进行基本测试 :

详解AOP与Filter拦截请求打印日志实用例子

5 . 控制台可以看到基本效果 :

详解AOP与Filter拦截请求打印日志实用例子

以上只是关于Controller应该记录日志的一个简单的例子,完整代码可见 https://github.com/EalenXie/springboot-controller-logger

来源:http://www.cnblogs.com/ealenxie/p/9618693.html

标签:AOP,Filter,拦截,打印日志
0
投稿

猜你喜欢

  • 解决JavaWeb读取本地json文件以及乱码的问题

    2023-09-14 18:35:14
  • Servlet+JDBC实现登陆功能的小例子(带验证码)

    2021-05-29 03:04:25
  • JavaMail入门教程之发送邮件(3)

    2023-02-01 20:01:16
  • java数据结构和算法中哈希表知识点详解

    2023-08-05 08:28:11
  • java基于包结构的请求路由实现实例分享

    2021-10-23 13:10:18
  • Java 按行读取文件按行写入文件并以空格分割字符串的方法

    2023-08-31 12:32:21
  • Java 反射调用静态方法的简单实例

    2021-10-09 06:47:58
  • java实现删除某条信息并刷新当前页操作

    2022-06-26 07:12:12
  • Jersey Restful接口如何获取参数的问题

    2023-10-29 14:44:16
  • java使用动态代理来实现AOP(日志记录)的实例代码

    2023-11-28 22:34:45
  • JAVA遍历一个文件夹中的所有文件的小例子

    2023-04-07 17:13:49
  • 带你详细了解Java值传递和引用传递

    2023-02-19 08:42:26
  • SpringBoot配置文件中密码属性加密的实现

    2022-07-08 18:32:03
  • Java 随机生成验证码(支持大小写字母、数字、随机字体)的实例

    2023-11-25 00:35:38
  • Java 实现repalceAll只替换第二个匹配到的字符串

    2021-06-12 11:56:20
  • Spring Bean初始化及销毁多种实现方式

    2023-06-10 13:14:01
  • seata-1.4.0安装及在springcloud中使用详解

    2023-02-21 00:49:21
  • 软件开发七大过程模型

    2023-12-22 17:06:14
  • JavaSE的类和对象你真的了解吗

    2021-09-17 21:14:59
  • java基础-数组扩容详解

    2022-05-24 00:34:58
  • asp之家 软件编程 m.aspxhome.com