问题描述
我在将 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.@R_404_1612@();
}
}
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);
}
观察: 我的观察是,当我通过这种方法将文件保存在磁盘上时,所有数据都会正确显示。 但在接收端保存的是空文件。
另一个观察结果是接收端的字节数组大小比发送端小。检查下图,
解决方法
所以我终于找到了解决我的问题的方法。我没有使用 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 Interceptor,它在我的请求中添加了一个令牌。
不过,使用 FeignClient 的解决方案将不胜感激。