在弹簧AOP中检索响应主体作为空字符串
我有一个要求,我需要将任何请求和响应保存给数据库中的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 namedCachedContent = {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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论