如何在Spring Aspect中获取HttpServletRequest主体

问题描述

我正在尝试记录每个完整请求内容,并且响应结果为Http Request

完整的请求内容意味着即使请求包含未导入的参数,该参数也应记录为RestController参数忽略。

例如,http请求正文为:

{
    a: 1,b: 2,c: 3
}

控制器是:

class TestParam {
    String a;
    String b;
}

@RestController
class TestController {
    
    @PostMapping("test")
    public String test(@RequestBody TestParam param) {
        //some handle...
    }
}

请求内容的日志应为:

{
    a: 1,c: 3
}

不是这个:

{
    a: 1,b: 2
}

我写了RestControllerAspect,这是我的代码

@Aspect
@Component
@Slf4j
public class RestControllerAspect {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;

    @Around("@within(org.springframework.web.bind.annotation.RestController)")
    public Object apiLog(ProceedingJoinPoint joinPoint) throws Throwable {

        String className = joinPoint.getSignature().getDeclaringTypeName();
        String classMethod = joinPoint.getSignature().getName();
        String ip = ServletUtil.getClientIP(request);
        UserAgent agent = UserAgentParser.parse(request.getHeader("user-agent"));

        if (request.getmethod().equalsIgnoreCase("options")) {
            return joinPoint.proceed();
        }

        log.info("********* request log *********");
        log.info("http method: {} {}",request.getmethod(),request.getRequestURI());
        log.info("class method: {} {}",className,classMethod);

        // read request inputstream to get full request
        // but throw exception: getInputStream() has already been called for this request
        log.info("full request: {}",ServletUtil.getBody(request.getInputStream());

        // getArgs only return the {a: 1,b: 2}
        log.info("args: " + JSON.toJSONString(joinPoint.getArgs()));
        log.info("remote ip: " + ip);
        log.info("request time: " + LocalDateTime.Now());

        Object res = joinPoint.proceed();
        // log response data
        log.info("response data: {}",JSON.toJSONString(res));
    }
}

代码所示,我无法读取HttpServeletRequest inputstream获取完整的请求内容

我真的不想使用过滤器来实现,因为它太麻烦了,无法编写代码

有人可以给我一些建议吗?非常感谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)