返回顶部
首页 > 资讯 > 后端开发 > Python >Springboot如何利用拦截器拦截请求信息收集到日志详解
  • 471
分享到

Springboot如何利用拦截器拦截请求信息收集到日志详解

2024-04-02 19:04:59 471人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1、需求2、问题2、获取1)导入依赖为了获取客户端类型、操作系统类型、ip、port2)封装获取body字符串的工具类3)拦截器类4)继承 httpservletRequestW

1、需求

最近在工作中遇到的一个需求,将请求中的客户端类型、操作系统类型、ip、port、请求方式、URI以及请求参数值收集到日志中,网上找资料说用拦截器拦截所有请求然后收集信息,于是就开始了操作:

2、问题

试了之后发现当请求方式为POST,前端发送数据JSON时只能用request.getReader()流获取,自信满满从流中获取之后发现请求之后报错:


getInputStream() has already been called for this request...

于是网上找答案,发现是ServletRequest的getReader()和getInputStream()两个方法只能被调用一次,而且不能两个都调用。那么如果Filter中调用了一次,在Controller里面就不能再调用了。

然后又开始找解决方法,说既然ServletInputStream不支持重新读写,就把流读出来后用容器存储起来,后面就可以多次利用了。

于是继承 HttpServletRequestWrapper类(http请求包装器,其基于装饰者模式实现了HttpServletRequest界面)并实现想要重新定义的方法以达到包装原生HttpServletRequest对象。还需要在过滤器里将原生的HttpServletRequest对象替换成我们的RequestWrapper对象。

测试发现POST请求参数值可以在拦截器类中获取到了,本以为大功告成,又发现GET请求不好使了,开始报错Stream closed,一顿操作发现需要在过滤器进行判断,如果是POST请求走自己的继承的HttpServletRequestWrapper类请求,否则走普通的请求。终于成功!突然舒服了。

2、获取

1)导入依赖为了获取客户端类型、操作系统类型、ip、port


<dependency>
            <groupId>eu.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
            <version>1.21</version>
</dependency>

2)封装获取body字符串的工具类


package com.btrc.access.util;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.NIO.charset.Charset;

public class RequestUtil {
    public static String getBodyString(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        try (
                InputStream inputStream = request.getInputStream();
               BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))
        ) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}

3)拦截器类


package com.btrc.access.filter;

import com.btrc.access.util.RequestUtil;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.WEB.servlet.HandlerInterceptor;

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


public class RequestInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("user-agent"));
        //客户端类型
        String clientType = userAgent.getOperatingSystem().getDeviceType().getName();
        //客户端操作系统类型
        String osType = userAgent.getOperatingSystem().getName();
        //客户端ip
        String clientIp = request.getRemoteAddr();
        //客户端port
        int clientPort = request.getRemotePort();
        //请求方式
        String requestMethod = request.getMethod();
        //客户端请求URI
        String requestURI = request.getRequestURI();
        //客户端请求参数值
        String requestParam;
        //如果请求是POST获取body字符串,否则GET的话用request.getQueryString()获取参数值
        if(StringUtils.equalsIgnoreCase(HttpMethod.POST.name(), requestMethod)){
            requestParam = RequestUtil.getBodyString(request);
        }else{
            requestParam = request.getQueryString();
        }
        //客户端整体请求信息
        StringBuilder clientInfo = new StringBuilder();
        clientInfo.append("客户端信息:[类型:").append(clientType)
                .append(", 操作系统类型:").append(osType)
                .append(", ip:").append(clientIp)
                .append(", port:").append(clientPort)
                .append(", 请求方式:").append(requestMethod)
                .append(", URI:").append(requestURI)
                .append(", 请求参数值:").append(requestParam.replaceAll("\\s*", ""))
                .append("]");
        
        /
@Configuration
public class WebmvcConfig implements WebMvcConfigurer {
    @Bean
    public FilterReGIStrationBean httpServletRequestReplacedFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AccessFilter());
        // /* 是全部的请求拦截,和Interceptor的拦截地址/**区别开
        registration.addUrlPatterns("/*");
        registration.setName("accessRequestFilter");
        registration.setOrder(1);
        return registration;
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");
    }
}

总结

到此这篇关于SpringBoot如何利用拦截器拦截请求信息收集到日志的文章就介绍到这了,更多相关Springboot拦截请求信息到日志内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Springboot如何利用拦截器拦截请求信息收集到日志详解

本文链接: https://lsjlt.com/news/132409.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作