Java Spring引导应用程序中序列化API请求参数的问题
我编写了一个方面来序列化Spring boot应用程序中API的请求参数,使用DB,如下所示:Java Spring引导应用程序中序列化API请求参数的问题,java,spring-boot,aspectj,spring-aop,objectmapper,Java,Spring Boot,Aspectj,Spring Aop,Objectmapper,我编写了一个方面来序列化Spring boot应用程序中API的请求参数,使用DB,如下所示: @Pointcut("within(com.tm.web.rest.*)") public void applicationResourcePointcut() { // Method is empty as this is just a Pointcut, the implementations are in the advices. } /**
@Pointcut("within(com.tm.web.rest.*)")
public void applicationResourcePointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
/**
* Advice that logs when a method is returned.
*
* @param joinPoint join point for advice
*/
@AfterReturning(value = ("applicationResourcePointcut()"),
returning = "returnValue")
public void capturePayloadWhileReturning(JoinPoint joinPoint, Object returnValue) {
CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature();
Map<String, Object> argumentNameValueMap = new HashMap<>();
if (codeSignature.getParameterNames() == null) {
return mapper.writeValueAsString(argumentNameValueMap);
}
for (int i = 0; i < codeSignature.getParameterNames().length; i++) {
String argumentName = codeSignature.getParameterNames()[i];
Object argumentValue = joinPoint.getArgs()[i];
argumentNameValueMap.put(argumentName, mapper.convertValue(argumentValue, Map.class));
}
String s = mapper.writeValueAsString(argumentNameValueMap);
}
对于HttpServletRequest
的请求类型,我得到了StackOverflow错误
事实上,我想避免这些类型的争论。但我无法找到正确处理这一问题的方法
有人能帮忙吗?乔伊,如果你问问题,尽量提供完整的答案,不要让志愿者帮你猜。在本例中,您在序列化数据时遇到问题,但您既没有提到您使用的序列化技术或工具,也没有从您的代码中识别它,因为aspect advice使用对象
映射器
,而您没有显示它是如何声明的。我不明白为什么这么多开发人员选择简洁而不是清晰
在谷歌搜索了mapper.writeValueAsString(..)
之后,我发现你可能使用了Jackson。我假设这是真的
toString()
的结果写入数据库。这就是你要问的吗?那你就可以
try
/catch
块构建动态列表,并将Jackson未能序列化的类添加到列表中,下次避免对同一类进行序列化,或者try
/catch
,返回到toString()
- 例如,由于
方法中的void
语句,它永远不会这样编译返回mapper.writeValueAsString(..)
- 您绑定
,但从不使用它returnValue
- 您可以在三个不同的位置调用
,其中一个在循环中,而不是将值缓存在局部变量中。这应该简化codeSignature.getParameterNames()
- 您可以将签名强制转换为
,而不是更一般的MethodSignature
。然后您就可以访问该方法的返回类型。SpringAOP无论如何都不支持拦截构造函数,只有AspectJ支持。假设您使用SpringAOP,唯一可以拦截的就是方法CodeSignature
- 我不明白为什么您对每个方法参数值调用
,试图将其转换为mapper.convertValue(..)
。为什么不直接使用Map
writeValueAsString(..)
- 检查
中的getParameterNames()
,但它从不返回null
,而是一个空数组。所以这个检查是没有必要的null
- 还请注意,只有在使用调试信息编译类时,存储参数名的整个想法才有效。否则就不会有任何真正的参数名,只有代理项,如
、arg0
等。因此,在实现这样的解决方案之前,您最好确保代码的编译方式正确arg1
- 在已经包含JSON对象的映射上调用
会导致像mapper.writeValueAsString(argumentNameValueMap)
这样的字符串再次被括在双引号中,比如“foo”
,这可能不是您想要的。确保每个对象只序列化一次“\“foo\”
package de.scrum_master.spring.q64782403;
导入org.springframework.stereotype.Component;
导入javax.servlet.http.HttpServletRequest;
导入java.io.ByteArrayInputStream;
@组成部分
公共类MyComponent{
公共无效剂量测定法(){
System.out.println(“做某事”);
}
公共整数相加(整数a、整数b){
系统输出打印项次(“添加”);
返回a+b;
}
public void someRequest(HttpServletRequest请求,字符串参数){
System.out.println(“处理请求”);
}
public void someByteStream(int索引,ByteArrayInputStream){
System.out.println(“处理字节数组输入流”);
}
公共字符串连接(字符串a、字符串b){
System.out.println(“连接”);
返回a+“”+b;
}
}
驱动程序应用程序:
package de.scrum_master.spring.q64782403;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.springframework.context.ConfigurableApplicationContext;
导入org.springframework.mock.web.MockHttpServletRequest;
导入java.io.ByteArrayInputStream;
@SpringBoot应用程序
公共类应用程序{
公共静态void main(字符串[]args){
try(ConfigurableApplicationContext上下文=SpringApplication.run(Application.class,args)){
多斯塔夫(上下文);
}
}
私有静态void doStuff(ConfigurableApplicationContext上下文){
MyComponent MyComponent=context.getBean(MyComponent.class);
myComponent.doSomething();
添加(4,5);
myComponent.SomeByTestStream(11,新的ByteArrayInputStream(新字节[1024]);
someRequest(新的MockHttpServletRequest(“GET”,“my/request”),“foo”);
连接(“你好”,“世界”);
}
}
请注意,对于这个虚拟应用程序,我只使用了MockHttpServletRequest
,因此如果您希望
java.lang.IllegalArgumentException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile["inputStream"])