提问者:小点点

如何在Spring过滤器中获取请求的身体参数?


我想通过Spring过滤器或方面记录超文本传输协议请求中的请求参数。我尝试了不同的方法,但请求参数为空或未调用方法。我使用的是POSTMAN,它是一个POST请求。

http://localhost:8080/available data

请求正文示例:

{“keyUserAgent”:“CFNetwork/1209 Darwin/20.2.0”,“locale”:“en_US”,“eid”:“8904977033”,“sessionId”:“VGA-G2020201030-776878787-1AD5-11EB-895C-H78789GJJH”}

方法1:这里调用了request()之前的“@Override”方法,但没有调用我创建的重载方法(我添加了@RequestBody以根据其他解决方案获取正文)。

@Component
public class CustomLoggingFilter extends AbstractRequestLoggingFilter {
      
            protected void beforeRequest(HttpServletRequest request, String message,@RequestBody RequestDTO requestBody) {
            requestBody.getKeyUserAgent();
            requestBody.getEid();
            System.out.println("Eid: "+requestBody.getEid());
            System.out.println("getKeyUserAgent: "+requestBody.getKeyUserAgent());
            
        }  
        
    }

方法2:这里它是空的

@Aspect
@Component
@Order(1)
public class LogAspect {

    private final static Logger logger = LoggerFactory.getLogger(LoggerAspect.class);
      @Around("allControllerMethods() && args(..,@annotation(org.springframework...RequestBody) requestBody) ")
      public Object controllerEvents(ProceedingJoinPoint jp, Object requestBody) throws Throwable {
            
          ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
             HttpServletRequest request = attributes.getRequest();
             MethodSignature signature = (MethodSignature) jp.getSignature();
              Method method = signature.getMethod();
              Object resObject = jp.proceed();
              Object sessionId = attributes.getSessionId()
              if (requestBody != null) {
                  String keyUserAgent = request.getParameter("keyUserAgent");
                  System.out.println("keyUserAgent : " + keyUserAgent);
                  
                }
              
          return resObject;
      } 

共1个答案

匿名用户

首先,从HttpRequest中读取数据以进行日志记录和后续处理存在一个问题,因为类< code>HttpServletRequest只允许读取其内容一次,任何重复读取它的尝试都会导致异常。因此,spring boot通过使用类< code > ContentCachingRequestWrapper 提供了一个解决方案。其思想是在过滤器中一次性读取请求的整个上下文,并将内容复制到允许多次读取的包装类中。之后,您继续使用您的包装类(间接实现HttpServletRequest)的链。现在,在您的一个过滤器(必须在用ContentCachingRequestWrapper替换HttpServletRequest的过滤器之后配置)中,您可以读取并记录您的请求参数,稍后您还可以读取您的请求以处理它。我在我们的项目中实现了这一点,效果非常好。这里有一些解释如何做的文章的链接。在Spring中多次读取HttpServletRequest,org . Spring framework . web . util . contentcachingrequestwrapper的Java代码示例