在弹簧AOP中检索响应主体作为空字符串

发布于 2025-02-09 21:37:07 字数 3933 浏览 0 评论 0原文

我有一个要求,我需要将任何请求和响应保存给数据库中的REST控制器,因此我决定实现Spring aop 。现在遇到的问题是我无法掌握任何请求主体。请求主体被检索为一个空字符串。 我的休息控制器都包裹在基本对象中,而AOP仅检测外部基类。

我的基类

public class BaseObject<T> {
    private T data;
}

具有这样的定义:

@PostMapping("/student")
    public BaseObject<StudentResponse> saveStudent(@RequestBody BaseObject<StudentRequest> studentRequest) {

目前

private void saveRequestInDatabase(ProceedingJoinPoint joinPoint, long time) {
        System.out.println("****************Inside saveRequestInDatabase method*****************");
        System.out.println(Thread.currentThread().getName());
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        DataBaseRequest dataBaseRequest = new DataBaseRequest();
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        dataBaseRequest.setMethod(className + "." + methodName + "()"); // class name and method name retrieved fine
        
        Object[] args = joinPoint.getArgs();
        System.out.println("Object Arguments :- " +joinPoint.getArgs()); // only has the Outer BaseObject, the data inside it is null
        
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        System.out.println("Param Names :- "+paramNames);
        if (args != null && paramNames != null) {
            String params = "";
            for (int i = 0; i < args.length; i++) {
                params += "  " + paramNames[i] + ": " + args[i]; // ***paramNames[] has the studentRequest variable name*** 
                                                                // ***args[] has the outer BaseObject but the data inside it, is null***
            }
            dataBaseRequest.setParams(params);
        }
        
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ContentCachingRequestWrapper req = new ContentCachingRequestWrapper(request);
        byte[] requestBody = req.getContentAsByteArray();
        String reqBodyStr = new String(requestBody, StandardCharsets.UTF_8);
        JsonObject jsonObject = new JsonObject();
        String reqBody = null;
        try {
            reqBody = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        jsonObject.addProperty("requestBody", reqBody); // ***requestBody is "" when being executed***
        jsonObject.addProperty("reqBody", reqBodyStr); // ***reqBody is "" when being executed***

        dataBaseRequest.setEndPoint(request.getServletPath()); // This is fetched fine
        dataBaseRequest.setOperation(request.getMethod()); // fetched fine
        dataBaseRequestService.saveRequest(dataBaseRequest);// saved inside database but the column to store reqObject has {data:null}
        System.out.println("((((((((((((((((Done saving request)))))))))))))))))))))");
    }

@Before("execution(your.package.where.is.endpoint.*.*(..)) && args(reqArgs)")

我的控制器方法 21216},data = null 。

我唯一可以看到我的请求主体是:内部httpservletrequest请求对象,有一个命名的属性 cachedContent = {bytearrayoutputstream@13221},它的json请求对象是从Postman(即抓住这一点。

请让我知道如何在baseObject上包裹时,如何获取请求对象(student obobject)和响应对象(student> student> student Response)。

谢谢!

I have a requirement wherein I need to save any request and response being passed to a Rest Controller in a database, so I decided to implement Spring AOP for the same. The issue that is now being encountered is I couldn't get hold of any of the request body. Request body is being retrieved as an empty string.
My Rest Controllers are all wrapped inside a Base Object and AOP only detects the outer Base class.

My Base Class :

public class BaseObject<T> {
    private T data;
}

My controller methods have definition like this :

@PostMapping("/student")
    public BaseObject<StudentResponse> saveStudent(@RequestBody BaseObject<StudentRequest> studentRequest) {

What I have tried till now :

private void saveRequestInDatabase(ProceedingJoinPoint joinPoint, long time) {
        System.out.println("****************Inside saveRequestInDatabase method*****************");
        System.out.println(Thread.currentThread().getName());
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        DataBaseRequest dataBaseRequest = new DataBaseRequest();
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        dataBaseRequest.setMethod(className + "." + methodName + "()"); // class name and method name retrieved fine
        
        Object[] args = joinPoint.getArgs();
        System.out.println("Object Arguments :- " +joinPoint.getArgs()); // only has the Outer BaseObject, the data inside it is null
        
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        System.out.println("Param Names :- "+paramNames);
        if (args != null && paramNames != null) {
            String params = "";
            for (int i = 0; i < args.length; i++) {
                params += "  " + paramNames[i] + ": " + args[i]; // ***paramNames[] has the studentRequest variable name*** 
                                                                // ***args[] has the outer BaseObject but the data inside it, is null***
            }
            dataBaseRequest.setParams(params);
        }
        
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ContentCachingRequestWrapper req = new ContentCachingRequestWrapper(request);
        byte[] requestBody = req.getContentAsByteArray();
        String reqBodyStr = new String(requestBody, StandardCharsets.UTF_8);
        JsonObject jsonObject = new JsonObject();
        String reqBody = null;
        try {
            reqBody = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        jsonObject.addProperty("requestBody", reqBody); // ***requestBody is "" when being executed***
        jsonObject.addProperty("reqBody", reqBodyStr); // ***reqBody is "" when being executed***

        dataBaseRequest.setEndPoint(request.getServletPath()); // This is fetched fine
        dataBaseRequest.setOperation(request.getMethod()); // fetched fine
        dataBaseRequestService.saveRequest(dataBaseRequest);// saved inside database but the column to store reqObject has {data:null}
        System.out.println("((((((((((((((((Done saving request)))))))))))))))))))))");
    }

I have also tried this :

@Before("execution(your.package.where.is.endpoint.*.*(..)) && args(reqArgs)")

Even here, reqArgs = {BaseObject@21216}, data = null.

The only place I could see my request body is: Inside the HttpServletRequest request object, there is an attribute named
CachedContent = {ByteArrayOutputStream@13221} which has my JSON request object that is being passed from Postman, i.e, all the attributes of StudentRequest object, but I don't know how to grab hold of the same.

Please let me know how can I get the request objects (StudentObject) and response objects (StudentResponse) when it is wrapped around the BaseObject.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文