由于公司内部使用dubbo作为远程服务调用,在使用其他系统的文件上传服务时,系统出现报错。
@ResponseBody
@RequestMapping(value = "uploadResourceImg", headers = "content-type=multipart/form-data", method = RequestMethod.POST)
public RestResult uploadImage(@RequestParam(value = "file", required = true) MultipartFile file) throws IOException {
GisResultDto uploadResult = commonUploadService.uploadImage(file.getBytes(), uploadToken);
log.info("uploadImage 上传图像:【{}】,地址:【{}】", file.getName(), uploadResult.getUrl());
return RestWrapper.makeOkRsp(uploadResult);
}
com.alibaba.fastjson.JSONException: write javaBean error, fastjson version 1.2.56, class org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile, fieldName : 0, write javaBean error, fastjson version 1.2.56, class org.springframework.web.multipart.MultipartFileResource, fieldName : resource
百度了一下,大致意思是序列化的时候出现了问题,所以在最初以为是服务调用的时候,序列化问题,网上说基本上都是要加上@JSONField(serialize=false)来对这个文件类型的字段进行序列化过滤,但是我们需要将这个文件作为参数去上传到对应的文件服务器,所以不能过滤。
后来,在controller入口加断点,发现没有进入,所以应该是在外部就进行了拦截,寻找对应的拦截器或者是切面,看看是否有拦截信息。
后来发现项目是SpringBoot框架,使用AOP进行异常日志拦截,要想json不继续报错,需要对其进行过滤如下:
@Aspect
@Component
@Slf4j
public class LogAop {
@Pointcut("execution(* cn.com.test..controller..*(..))")
public void logPointcut() {
}
@Around("logPointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String uri = sra == null ? "" : sra.getRequest().getRequestURI();
Signature signature = pjp.getSignature();
String methodName = signature.getName();
long begin = System.currentTimeMillis();
Object[] args = pjp.getArgs();
StringBuilder sb = new StringBuilder();
for (Object arg : args) {
//对MultipartFile进行过滤即可
if (arg instanceof MultipartFile){
continue;
}
if (sb.length() > 0) sb.append(", ");
sb.append(stringArg(arg));
}
String params = sb.toString();
String ret = null;
try {
Object result = pjp.proceed();
ret = JSON.toJSONString(result);
return result;
} catch (Throwable th) {
ret = "ex: " + th.getClass().getSimpleName() + ": " + th.getMessage();
throw th;
} finally {
long cost = System.currentTimeMillis() - begin;
log.info("LogAop uri:{}, method:{}, cost:{}, req:{}, result:{}", uri, methodName, cost, params, ret);
}
}
private String stringArg(Object arg){
if(arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {
return arg.toString();
}
// 非POJO的参数用JSON转化可能抛出异常
return JSON.toJSONString(arg);
}
}
添加后正常使用,文件上传成功。