0

我在将 MultipartFile 从一项服务发送到另一项服务时遇到问题。

我想调用的 API 是,

@PostMapping(value = "/posts/{postId}/comments/{commentId}/attachments")
@JsonView(CaseJsonView.ClientWithComments.class)
public ResponseEntity<?> createCommentAttachment(@PathVariable final String postId, @PathVariable final String commentId, @RequestParam("payload") final MultipartFile multipartFile, @RequestParam final String filename, final HttpServletRequest request) throws JsonProcessingException {
        try {
            FileUtils.writeByteArrayToFile(new File("C:\\CODE\\data\\" + filename), multipartFile.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
}

当我像下面这样调用这个 API 时,这里会创建空文件,

FeignClient

@FeignClient(name = "post-service")
public interface CommentClient {
    @RequestMapping(method = RequestMethod.POST, value = "/posts/{postId}/comments/{id}/attachments?filename={filename}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    void storeCommentAttachmentPayload(@PathVariable("postId") String postId, @PathVariable("id") String id, @RequestBody MultiValueMap<String, Object> map, @PathVariable("filename") String filename);
}

我正在使用这个 FeignClient,如下所示,

public void sendAttachment() {
   //Adding only attachment code.
   // Here attachmentClient is some other FeignClient which is returning attachment.
   final Resource resource = attachmentClient.getAttachmentPayloadById(attachementId);
                final MultipartFile multipartFile = new InMemoryMultipartFile(filename, filename, 
   mimeType, IOUtils.toByteArray(resource.getInputStream()));
                final MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
                final ByteArrayResource byteArrayResource = new 
   ByteArrayResource(multipartFile.getBytes()) {
                    @Override
                    public String getFilename() {
                        return filename == null ? "" : filename;
                    }
                };
   map.add(PAYLOAD, byteArrayResource);
   commentService.storeCommentAttachmentPayload(postId commentId, map, filename);
}

观察:我的观察是,当我通过这种方法将文件保存在磁盘上时,所有数据都会正确显示。但是在接收端保存了空文件。

另一个观察结果是,接收端的字节数组大小比发送端小。检查下图, https://i.stack.imgur.com/JjxEZ.png

另一项观察是文本文件已正确上传。

4

1 回答 1

0

所以最后我找到了解决我的问题的方法。我没有使用 FeignClient 上传文件,而是使用 RestTemplate 上传,如下所示,

final List<ServiceInstance> postServiceInstances = discoveryClient.getInstances("post-service");
                if (postServiceInstances != null && !postServiceInstances.isEmpty()) {
                    final HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<MultiValueMap<String, Object>>(multiValuMap);
                    final ResponseEntity<String> response = restTemplate
                            .postForEntity(postServiceInstances.get(0).getUri() + "/posts/" + postId + "/comments/" + commentId + "/attachments?filename=" + filename, entity, String.class);
                    if (response.getStatusCode() != HttpStatus.CREATED) {
                        throw new Exception("Exception from post-service: " + response.getStatusCode());
                    }
                } else {
                    throw new Exception("No post-service instance found");
                }

实际上不是一个完美的解决方案,但它正在解决我的目的。另外,我添加了 RestTemplate 拦截器,它在我的请求中添加了一个令牌。

不过,使用 FeignClient 的解决方案将不胜感激。

于 2021-02-26T11:33:27.997 回答