servicecomb-java-chassis
servicecomb-java-chassis copied to clipboard
RPC批量文件上传接口调用问题
RPC批量文件上传接口调用问题
- 问题背景
A服务定义文件上传接口,如下图所示
代码如下
@RequestMapping(path = "/fileupload/v1", produces = MediaType.APPLICATION_JSON)
@RestSchema(schemaId = "file-upload")
public class FileUploadApiController {
// 单个文件上传
@RequestMapping(value = "/file/upload", produces = {"application/json"}, consumes = {"multipart/form-data"},
method = RequestMethod.POST)
@ApiOperation(value = "上传文件(私有桶)", tags = {"FileUpload"})
@ApiResponses(value = {@ApiResponse(code = 200, message = "响应消息体", response = FileUploadResponse.class)})
public FileUploadResponse uploadFile(@NotNull @RequestPart(value = "file", required = true) MultipartFile file) {
return fileUploadApiFileUploadDelegate.uploadFile(file);
}
// 批量文件上传
@RequestMapping(value = "/files/upload", produces = {"application/json"}, consumes = {"multipart/form-data"},
method = RequestMethod.POST)
@ApiOperation(value = "上传文件(私有桶)", tags = {"FileUpload"})
@ApiResponses(value = {@ApiResponse(code = 200, message = "响应消息体", response = FilesUploadResponse.class)})
public FilesUploadResponse uploadFiles(
@NotNull @RequestPart(value = "files", required = true) MultipartFile[] files) {
return fileUploadApiFileUploadDelegate.uploadFiles(files);
}
}
B服务通过RPC方式调用A服务的接口 代码如下
// RPC 接口定义
public interface FileUploadService {
FileUploadResponse uploadFile(File file);
FilesUploadResponse uploadFiles(File[] files);
}
public class FileUploadServiceImpl implements FileUploadService {
private static final String MICROSERVICE_NAME = "WeLinkLiteService:WeLinkLiteCommonService";
private static final String SCHEMA_ID_ORG_MGMT = "file-upload";
@RpcReference(microserviceName = MICROSERVICE_NAME, schemaId = SCHEMA_ID_ORG_MGMT)
private FileUploadService fileUploadService;
@Override
public FileUploadResponse uploadFile(File file) {
return fileUploadService.uploadFile(file);
}
@Override
public FilesUploadResponse uploadFiles(File[] files) {
return fileUploadService.uploadFiles(files);
}
}
调用报错如下
CSE日志有空指针异常
上面代码中,单个文件接口调用时OK的,仿照单个文件上传写了文件数组上传,但是RPC调不通,包上面所述的错误。 参考下面刘宝提供的GitHub上的实例又尝试了下面示例代码中的三种RPC接口定义方式,结果都不行。 service端 Client端
// 1. 入参定义为map Map
FilesUploadResponse uploadFiles(Map<String, Object> files);
// 2. 入参定义为File数组
FilesUploadResponse uploadFiles(FileSystemResource[] files);
// 3. 入参定义为MultipartFile数组
FilesUploadResponse uploadFiles(MultipartFile[] files);
补充
问题版本是 Java-Chassis 1.3.6
目前定位出来是
https://github.com/apache/servicecomb-java-chassis/blob/c2655de8ee5c0c4715708982cadc19e841d203ec/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperFactory.java#L231
这一行代码获取converter出了问题. RPC调用单文件上传场景拿到的是FileToPartConverter, 而List文件上传拿到的却是ConverterCommon, 导致文件上传参数转换出了问题.
进而在
https://github.com/apache/servicecomb-java-chassis/blob/c2655de8ee5c0c4715708982cadc19e841d203ec/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java#L194
这一行拿到的part为null, 引起空指针异常.
close old issues, please feel free to submit a new one if the problem still exists.