欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在SpringBoot框架中實(shí)現(xiàn)打印響應(yīng)的日志

 更新時(shí)間:2024年05月22日 09:05:08   作者:小子寶丁  
這篇文章主要介紹了在SpringBoot框架中實(shí)現(xiàn)打印響應(yīng)的日志,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

SpringBoot框架中打印響應(yīng)的日志

在 Spring Boot 框架中,可以使用攔截器來打印響應(yīng)的日志。

通過自定義一個(gè)攔截器,可以在響應(yīng)返回給客戶端之前捕獲響應(yīng)信息,并將其記錄到日志中。

以下是在 Spring Boot 框架中打印響應(yīng)日志的步驟:

1.創(chuàng)建一個(gè)攔截器類并實(shí)現(xiàn)HandlerInterceptor接口

例如,您可以創(chuàng)建一個(gè)名為 ResponseLoggingInterceptor 的類。

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class ResponseLoggingInterceptor implements HandlerInterceptor {

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在響應(yīng)返回給客戶端之后被調(diào)用
        // 記錄響應(yīng)信息到日志
        String logMessage = "RESPONSE - " +
                "Status: " + response.getStatus() +
                " | Request URI: " + request.getRequestURI();
        // 使用日志框架打印日志,例如使用 SLF4J: LoggerFactory.getLogger(ResponseLoggingInterceptor.class).info(logMessage);
    }
}

在上面的示例中,我們在 postHandle 方法中記錄響應(yīng)的狀態(tài)碼和請求的URI。

您可以根據(jù)需要擴(kuò)展此方法,記錄更多的響應(yīng)信息。

2.注冊攔截器

在您的配置類中,將攔截器注冊到 Spring Boot 應(yīng)用程序中。

import org.springframework.context.annotation.Configuration;
   import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
   import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

   @Configuration
   public class WebConfig implements WebMvcConfigurer {

       @Override
       public void addInterceptors(InterceptorRegistry registry) {
           registry.addInterceptor(new ResponseLoggingInterceptor());
       }
   }

在上述示例中,我們實(shí)現(xiàn)了 WebMvcConfigurer 接口,并重寫了 addInterceptors 方法。

在該方法中,我們將自定義的攔截器 ResponseLoggingInterceptor 添加到攔截器注冊表中。

3.運(yùn)行應(yīng)用程序

現(xiàn)在,當(dāng)您運(yùn)行 Spring Boot 應(yīng)用程序并發(fā)送請求時(shí),攔截器將捕獲每個(gè)響應(yīng)并將其記錄到日志中。

請注意:

  • 攔截器記錄的日志將在每個(gè)請求的響應(yīng)之后生成。
  • 這意味著攔截器不會(huì)記錄在發(fā)生錯(cuò)誤或異常時(shí)的響應(yīng)。
  • 如果您需要記錄這些情況下的響應(yīng),您可能需要結(jié)合異常處理機(jī)制來實(shí)現(xiàn)。

SpringBoot日志打印的幾種方式

記錄一下springboot日志打印的三種方式,過濾器、攔截器、AOP

1.過濾器

創(chuàng)建LogFilter類實(shí)現(xiàn)Filter接口

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

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

@Component
public class LogFilter implements Filter {

    private static final Logger LOG = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 打印請求信息
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        LOG.info("------------- LogFilter 開始 -------------");
        LOG.info("請求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        LOG.info("遠(yuǎn)程地址: {}", request.getRemoteAddr());

        long startTime = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        LOG.info("------------- LogFilter 結(jié)束 耗時(shí):{} ms -------------", System.currentTimeMillis() - startTime);
    }
}

2.攔截器

(1)創(chuàng)建LogInterceptor類實(shí)現(xiàn)HandlerInterceptor接口

import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;

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

 /**
  * 攔截器:Spring框架特有的,常用于登錄校驗(yàn),權(quán)限校驗(yàn),請求日志打印 /login
  */
 @Component
 public class LogInterceptor implements HandlerInterceptor {

     private static final Logger LOG = LoggerFactory.getLogger(LogInterceptor.class);

     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         // 打印請求信息
         LOG.info("------------- LogInterceptor 開始 -------------");
         LOG.info("請求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
         LOG.info("遠(yuǎn)程地址: {}", request.getRemoteAddr());

         long startTime = System.currentTimeMillis();
         request.setAttribute("requestStartTime", startTime);
         return true;
     }

     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         long startTime = (Long) request.getAttribute("requestStartTime");
         LOG.info("------------- LogInterceptor 結(jié)束 耗時(shí):{} ms -------------", System.currentTimeMillis() - startTime);
     }
 }

(2)創(chuàng)建SpringMvcConfig配置類實(shí)現(xiàn)WebMvcConfigurer接口,將上述類注冊到配置類中

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Resource
    LogInterceptor logInterceptor;

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(logInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns();
    }

}

3.AOP

(1)打開pom.xml,添加AOP依賴

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

(2)添加fastjson依賴,對于本代碼來說是必須的,因?yàn)楸敬a在使用AOP時(shí)想要排除敏感字段,需要fastjson下的JSONObject。如果只是單純的使用AOP是不需要這個(gè)依賴的

		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>

(3)創(chuàng)建LogAspect類

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class LogAspect {

    private final static Logger LOG = LoggerFactory.getLogger(LogAspect.class);

    /** 定義一個(gè)切點(diǎn) */
    @Pointcut("execution(public * com.jiawa.*.controller..*Controller.*(..))")
    public void controllerPointcut() {}

    @Before("controllerPointcut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {

        // 開始打印請求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();

        // 打印請求信息
        LOG.info("------------- 開始 -------------");
        LOG.info("請求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        LOG.info("類名方法: {}.{}", signature.getDeclaringTypeName(), name);
        LOG.info("遠(yuǎn)程地址: {}", request.getRemoteAddr());

        // 打印請求參數(shù)
        Object[] args = joinPoint.getArgs();
		// LOG.info("請求參數(shù): {}", JSONObject.toJSONString(args));

		Object[] arguments  = new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof ServletRequest
                    || args[i] instanceof ServletResponse
                    || args[i] instanceof MultipartFile) {
                continue;
            }
            arguments[i] = args[i];
        }
        // 排除字段,敏感字段或太長的字段不顯示
        String[] excludeProperties = {"password", "file"};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();
        excludefilter.addExcludes(excludeProperties);
        LOG.info("請求參數(shù): {}", JSONObject.toJSONString(arguments, excludefilter));
    }

    @Around("controllerPointcut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

//        執(zhí)行業(yè)務(wù)
        Object result = proceedingJoinPoint.proceed();

        // 排除字段,敏感字段或太長的字段不顯示
        String[] excludeProperties = {"password", "file"};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();
        excludefilter.addExcludes(excludeProperties);
        LOG.info("返回結(jié)果: {}", JSONObject.toJSONString(result, excludefilter));
        LOG.info("------------- 結(jié)束 耗時(shí):{} ms -------------", System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * 使用nginx做反向代理,需要用該方法才能取到真實(shí)的遠(yuǎn)程IP
     * @param request
     * @return
     */
    public String getRemoteIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • jpa異常No entity found for query問題解決

    jpa異常No entity found for query問題解決

    這篇文章主要為大家介紹了jpa異常之No entity found for query的異常問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • java線程池實(shí)戰(zhàn)應(yīng)用步驟詳解

    java線程池實(shí)戰(zhàn)應(yīng)用步驟詳解

    這篇文章主要介紹了java線程池實(shí)戰(zhàn)應(yīng)用小結(jié),包括線程池的創(chuàng)建方式,本文給大家分享兩種方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2025-04-04
  • 詳解如何通過Java實(shí)現(xiàn)壓縮PDF文檔

    詳解如何通過Java實(shí)現(xiàn)壓縮PDF文檔

    PDF文檔是我們?nèi)粘^k公中使用最頻繁的文檔格式。但因?yàn)榇蠖鄶?shù)PDF文檔都包含很多頁面圖像或大量圖片,這就導(dǎo)致PDF文檔過大,處理起來較為麻煩。本文將介紹如何通過Java應(yīng)用程序壓縮PDF文檔,需要的可以了解一下
    2022-12-12
  • Java 順序表專題解讀

    Java 順序表專題解讀

    順序表,全名順序存儲(chǔ)結(jié)構(gòu),是線性表的一種。線性表用于存儲(chǔ)邏輯關(guān)系為“一對一”的數(shù)據(jù),順序表自然也不例外,不僅如此,順序表對數(shù)據(jù)物理存儲(chǔ)結(jié)構(gòu)也有要求。順序表存儲(chǔ)數(shù)據(jù)時(shí),會(huì)提前申請一整塊足夠大小的物理空間,然后將數(shù)據(jù)依次存儲(chǔ)起來,存儲(chǔ)時(shí)數(shù)據(jù)元素間不留縫隙
    2021-11-11
  • MyBatisPlus+Lombok實(shí)現(xiàn)分頁功能的方法詳解

    MyBatisPlus+Lombok實(shí)現(xiàn)分頁功能的方法詳解

    Lombok是一個(gè)Java類庫,提供了一組注解,簡化POJO實(shí)體類開發(fā)。本文將為大家介紹一下Lombok的使用以及如何利用MyBatisPlus+Lombok實(shí)現(xiàn)分頁功能,感興趣的可以動(dòng)手嘗試一下
    2022-07-07
  • 如何使用Spring Security手動(dòng)驗(yàn)證用戶的方法示例

    如何使用Spring Security手動(dòng)驗(yàn)證用戶的方法示例

    這篇文章主要介紹了如何使用Spring Security手動(dòng)驗(yàn)證用戶的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-05-05
  • 基于java中BlockingQueue的使用介紹

    基于java中BlockingQueue的使用介紹

    本篇文章小編為大家介紹,基于java中BlockingQueue的使用介紹。需要的朋友參考下
    2013-04-04
  • Java中的注解和反射實(shí)例詳解

    Java中的注解和反射實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Java中注解和反射的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java異常處理操作實(shí)例小結(jié)

    Java異常處理操作實(shí)例小結(jié)

    這篇文章主要介紹了Java異常處理操作,結(jié)合實(shí)例形式總結(jié)分析了java異常處理常見操作情況與相關(guān)處理技巧,需要的朋友可以參考下
    2019-07-07
  • java 數(shù)據(jù)結(jié)構(gòu) 冒泡排序?qū)崿F(xiàn)代碼

    java 數(shù)據(jù)結(jié)構(gòu) 冒泡排序?qū)崿F(xiàn)代碼

    這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu) 冒泡排序的相關(guān)資料,并附實(shí)例代碼,有需要的小伙伴可以參考下
    2016-09-09

最新評論