servicecomb-java-chassis icon indicating copy to clipboard operation
servicecomb-java-chassis copied to clipboard

RPC批量文件上传接口调用问题

Open nanshankafei opened this issue 3 years ago • 1 comments

RPC批量文件上传接口调用问题

  1. 问题背景 A服务定义文件上传接口,如下图所示 image 代码如下
@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);
    }
}

调用报错如下 image 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);

nanshankafei avatar Jan 27 '22 06:01 nanshankafei

补充

问题版本是 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 这一行拿到的partnull, 引起空指针异常.

yhs0092 avatar Feb 10 '22 02:02 yhs0092

close old issues, please feel free to submit a new one if the problem still exists.

liubao68 avatar Dec 30 '22 09:12 liubao68