Retrieving the response body as an empty string in Spring AOP

719 Views Asked by At

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!

0

There are 0 best solutions below