如何在春季过滤器中获得请求体参数?



我想通过Spring过滤器或方面记录http请求中的请求参数。我尝试了不同的方法,但请求参数为空或方法未被调用。我正在使用邮差,这是一个POST请求

http://localhost: 8080/AvailableData

请求正文:

{"keyUserAgent"达尔文CFNetwork/1209/20.2.0","locale":"en_US","eid":"8904977033","sessionId":"vga - g20201030 - 776878787 - 1 - ad5 - 11 - eb - 895 c - h78789gjjh"}

方法1:here "@Override"方法被调用,但是我创建的重载方法没有被调用(我根据其他解决方案添加了@RequestBody来获取body)。

@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:这里是null

@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;
} 

首先,从HttpRequest读取数据用于日志记录和稍后的处理存在一个问题,因为类HttpServletRequest只允许读取其内容一次,并且任何重复读取它的尝试都会导致异常。因此,弹簧启动为使用ContentCachingRequestWrapper类提供了一种解决方案。其思想是,在过滤器中读取一次请求的整个上下文,并将内容复制到允许多次读取的包装器类中。之后,使用包装器类(间接实现HttpServletRequest)继续这个链。所以现在在你的过滤器之一(必须在用ContentCachingRequestWrapper代替HttpServletRequest的过滤器之后配置),你可以读取和记录你的请求参数,以后你仍然可以读取你的请求来处理它。我在我们的项目中实现了这一点,它像一个魅力。这里有一些文章的链接来解释如何做到这一点。在Spring中多次读取HttpServletRequest, Java代码示例

TL;DR

如何在春季过滤器中获得请求体参数?

一个好的做法是使用javax.servlet过滤器链是一个拦截器,它是由servlet容器提供的抽象,为资源的过滤请求的调用链提供视图。过滤器使用FilterChain调用链中的下一个过滤器,或者如果调用过滤器是链中的最后一个过滤器,则调用链末尾的资源。

@Component
static class RequestSizeFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
...
//access HttpServletRequest request data 
...
filterChain.doFilter(request, response);
}
}

同样的功能也可以用过滤器来实现,请参阅这个示例以获得正确的bean注册。

最新更新