一、问题概述
前段时间加了个aop日志切面打印,根据注解将入参信息全部打印出来。
在遇到上传文件这个接口时突然报了下面的错误,
错误对应关键代码,详见下面代码块11行。
2022-03-24 12:03:16.829 ERROR 1 --- [nio-8080-exec-4] c.i.x.exception.GlobalExceptionHandler : write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile, write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.MultipartFileResource, fieldName : resource
com.alibaba.fastjson.JSONException: write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile, write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.MultipartFileResource, fieldName : resource
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:539) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:149) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:312) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:769) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:707) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:672) ~[fastjson-1.2.75.jar!/:na]
at com.itheima.xiaotuxian.aspect.LogAspect.preHandle(LogAspect.java:119) ~[webCommon-1.0.0.jar!/:1.0.0]
at com.itheima.xiaotuxian.aspect.LogAspect.handle(LogAspect.java:56) ~[webCommon-1.0.0.jar!/:1.0.0]
at jdk.internal.reflect.GeneratedMethodAccessor127.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at com.itheima.xiaotuxian.controller.material.PictureController$EnhancerBySpringCGLIB$fc0b9216.savePicture(<generated>) ~[classes!/:1.0.0]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.37.jar!/:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.37.jar!/:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.37.jar!/:9.0.37]
at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: com.alibaba.fastjson.JSONException: write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.MultipartFileResource, fieldName : resource
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:539) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:149) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.FieldSerializer.writeValue(FieldSerializer.java:318) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:470) ~[fastjson-1.2.75.jar!/:na]
... 66 common frames omitted
Caused by: java.io.FileNotFoundException: MultipartFile resource [file] cannot be resolved to absolute file path
at org.springframework.core.io.AbstractResource.getFile(AbstractResource.java:138) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at com.alibaba.fastjson.util.FieldInfo.get(FieldInfo.java:571) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.FieldSerializer.getPropertyValueDirect(FieldSerializer.java:143) ~[fastjson-1.2.75.jar!/:na]
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:282) ~[fastjson-1.2.75.jar!/:na]
... 69 common frames omitted
二、原因和解决方案
修改前,打印日志方法(报错行17行)
………………省略
private String preHandle(ProceedingJoinPoint joinPoint, HttpServletRequest request) {
StringBuilder reqParam = new StringBuilder();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
java.lang.reflect.Method targetMethod = methodSignature.getMethod();
Object[] args = joinPoint.getArgs();
Annotation[][] parameterAnnotations = targetMethod.getParameterAnnotations();
int i = 0;
for (Annotation[] annotations : parameterAnnotations) {
for1: for (Annotation annotation : annotations) {
if (annotation instanceof RequestParam) {
reqParam.append(((RequestParam) annotation).name()).append(":").append(JSON.toJSONString(args[i]))
.append(",");
i++;
break for1;
} else if (annotation instanceof PathVariable) {
reqParam.append(JSON.toJSONString(args[i])).append(",");
i++;
break for1;
} else if (annotation instanceof RequestBody) {
reqParam.append(JSON.toJSONString(args[i])).append(",");
i++;
break for1;
}
}
}
return reqParam.toString();
}
………………省略
报错信息主要是:
write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile, write javaBean error, fastjson version 1.2.75, class org.springframework.web.multipart.MultipartFileResource, fieldName : resource
和MultipartFile resource [file] cannot be resolved to absolute file path
出错原因:MultipartFile文件无法转成JSON串
三、解决方案
分析知道了,是日志打印导致的。
切面日志将file转json,并打印了出来,此时转json失败了。
接口如下:
@Slf4j
@RestController
@RequestMapping("/material/picture")
public class PictureController extends BaseController {
@PostMapping
public MaterialUploadResultVo savePicture(@RequestParam(name = "file") MultipartFile file
, @RequestParam(name = "isMask", defaultValue = "false") Boolean isMask
, @RequestParam(name = "styleWidth", required = false) Integer styleWidth
, @RequestParam(name = "groupId", required = false) String groupId
, @RequestParam(name = "id", required = false) String id) {
// TODO 处理业务
return ;
}
}
切面日志代码,将@RequestParam(name = "file") MultipartFile file转成json,然后进行打印,此处,在转换json的时候,报错了,报错如问题概述中描述的
解决方案:增加判断20-24行已经解决了
修改后的切面日志如下
@Aspect
@Component
@Slf4j
public class LogAspect {
private String preHandle(ProceedingJoinPoint joinPoint, HttpServletRequest request) {
StringBuilder reqParam = new StringBuilder();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
java.lang.reflect.Method targetMethod = methodSignature.getMethod();
Object[] args = joinPoint.getArgs();
Annotation[][] parameterAnnotations = targetMethod.getParameterAnnotations();
int i = 0;
for (Annotation[] annotations : parameterAnnotations) {
for1: for (Annotation annotation : annotations) {
if (annotation instanceof RequestParam) {
if(args[i] instanceof MultipartFile){
reqParam.append(((RequestParam) annotation).name()).append(":").append(((MultipartFile)args[i]).getOriginalFilename())
.append(",");
}else{
reqParam.append(((RequestParam) annotation).name()).append(":").append(JSON.toJSONString(args[i]))
.append(",");
}
i++;
break for1;
} else if (annotation instanceof PathVariable) {
reqParam.append(JSON.toJSONString(args[i])).append(",");
i++;
break for1;
} else if (annotation instanceof RequestBody) {
reqParam.append(JSON.toJSONString(args[i])).append(",");
i++;
break for1;
}
}
}
return reqParam.toString();
}
}
四、总结
在面对日志打印中,一定要小心特殊参数,防止一些参数不能序列化
五、参考
1、记vue+elementUI+springBoot上传文件时因日志切面引起的错误
https://blog.csdn.net/weixin_44405225/article/details/107430765