最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

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

例如,您可以創(chuàng)建一個名為 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ù)需要擴展此方法,記錄更多的響應(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());
       }
   }

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

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

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

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

請注意:

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

SpringBoot日志打印的幾種方式

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

1.過濾器

創(chuàng)建LogFilter類實現(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("遠程地址: {}", request.getRemoteAddr());

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

2.攔截器

(1)創(chuàng)建LogInterceptor類實現(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框架特有的,常用于登錄校驗,權(quá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("遠程地址: {}", 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é)束 耗時:{} ms -------------", System.currentTimeMillis() - startTime);
     }
 }

(2)創(chuàng)建SpringMvcConfig配置類實現(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依賴,對于本代碼來說是必須的,因為本代碼在使用AOP時想要排除敏感字段,需要fastjson下的JSONObject。如果只是單純的使用AOP是不需要這個依賴的

		<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);

    /** 定義一個切點 */
    @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("遠程地址: {}", 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é)束 耗時:{} ms -------------", System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * 使用nginx做反向代理,需要用該方法才能取到真實的遠程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é)

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

相關(guān)文章

  • 全網(wǎng)最精細詳解二叉樹,2萬字帶你進入算法領(lǐng)域

    全網(wǎng)最精細詳解二叉樹,2萬字帶你進入算法領(lǐng)域

    大家好,我是哪吒,一個熱愛編碼的Java工程師,本著"欲速則不達,欲達則欲速"的學(xué)習(xí)態(tài)度,在程序猿這條不歸路上不斷成長,所謂成長,不過是用時間慢慢擦亮你的眼睛,少時看重的,年長后卻視若鴻毛,少時看輕的,年長后卻視若泰山,成長之路,亦是漸漸放下執(zhí)念,內(nèi)心歸于平靜的旅程
    2021-08-08
  • idea maven 項目src下的配置文件沒有同步至target的解決操作

    idea maven 項目src下的配置文件沒有同步至target的解決操作

    這篇文章主要介紹了idea maven 項目src下的配置文件沒有同步至target的解決操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • springboot application.properties 文件注入數(shù)組方式

    springboot application.properties 文件注入數(shù)組方式

    這篇文章主要介紹了springboot application.properties 文件注入數(shù)組方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • jenkins中如何集成commander應(yīng)用的完整步驟

    jenkins中如何集成commander應(yīng)用的完整步驟

    jenkins是一個用java編寫的開源的持續(xù)集成工具,在與oracle發(fā)生爭執(zhí)后,項目從hudson項目獨立出來,下面這篇文章主要給大家介紹了關(guān)于jenkins中如何集成commander應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-05-05
  • SpringBoot+Quartz實現(xiàn)定時任務(wù)的代碼模版分享

    SpringBoot+Quartz實現(xiàn)定時任務(wù)的代碼模版分享

    quartz?是一款開源且豐富特性的Java?任務(wù)調(diào)度庫,用于實現(xiàn)任務(wù)調(diào)度和定時任務(wù),本文主要和大家分享一個SpringBoot整合Quartz實現(xiàn)定時任務(wù)的代碼模版,需要的可以參考一下
    2023-06-06
  • idea中提示Class 'xxx' is never used的解決

    idea中提示Class 'xxx' is never us

    這篇文章主要介紹了idea中提示Class 'xxx' is never used的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java獲取文件夾下所有文件名稱的方法示例

    Java獲取文件夾下所有文件名稱的方法示例

    這篇文章主要介紹了Java獲取文件夾下所有文件名稱的方法,涉及java針對文件與目錄相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程詳解

    es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程詳解

    這篇文章主要介紹了es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • 學(xué)習(xí)C語言對后期java有幫助嗎

    學(xué)習(xí)C語言對后期java有幫助嗎

    在本篇文章里小編給大家整理的是一篇關(guān)于學(xué)習(xí)C語言對后期java有幫助嗎的基礎(chǔ)文章,有興趣的朋友們可以參考下。
    2020-11-11
  • Java之while與do-while循環(huán)的用法詳解

    Java之while與do-while循環(huán)的用法詳解

    在上一篇文章中,給大家講解了循環(huán)的概念,并重點給大家講解了for循環(huán)的使用。但在Java中,除了for循環(huán)之外,還有while、do-while、foreach等循環(huán)形式。這篇文章給大家講解while循環(huán)的使用
    2023-05-05

最新評論

日照市| 郸城县| 沙坪坝区| 澄江县| 马关县| 横山县| 舟曲县| 维西| 司法| 信宜市| 隆子县| 罗甸县| 乐东| 西乌珠穆沁旗| 泾源县| 平果县| 汉源县| 泰兴市| 兴业县| 西安市| 乐东| 莫力| 大安市| 贺兰县| 大竹县| 八宿县| 百色市| 延吉市| 武邑县| 古交市| 德阳市| 和平县| 科技| 会宁县| 朝阳市| 长岛县| 连平县| 乡宁县| 泾源县| 巴彦淖尔市| 长沙县|