Java 隧道 MultipartFile
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22630550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tunneling MultipartFile
提问by Avi
I have a spring
controller that accepts a class named FileUploadBean
on POST
. The controller method looks like that:
我有一个spring
控制器,它接受一个名为FileUploadBean
on的类POST
。控制器方法如下所示:
First Controller:
第一控制器:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<byte[]> uploadFile(final FileUploadBean fileUploadBean) throws IOException {
// Some code that works fine here
}
One of the FileUploadBean
properties is of type MultipartFile
.
其中一个的FileUploadBean
属性是类型MultipartFile
。
Now, I'm trying to add some sort of wrapper controller (that will run on another server) that also accepts FileUploadBean
and just forwards the request to the first controller:
现在,我正在尝试添加某种包装控制器(将在另一台服务器上运行),它也接受FileUploadBean
并将请求转发到第一个控制器:
Second (wrapper) Controller:
第二个(包装器)控制器:
@RequestMapping(value="/upload", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<byte[]> uploadImage(final FileUploadBean fileUploadBean) throws IOException {
ResponseEntity<byte[]> response = restTemplate.postForEntity([first controller url here], fileUploadBean, byte[].class);
return response;
}
When I'm sending the request to the first controller I get:
当我将请求发送到第一个控制器时,我得到:
org.springframework.http.converter.HttpMessageNotWritableException:
Could not write JSON: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.outbrain.images.beans.FileUploadBean["file"]->org.springframework.web.multipart.commons.CommonsMultipartFile["fileItem"]->org.apache.commons.fileupload.disk.DiskFileItem["inputStream"]->java.io.FileInputStream["fd"]); nested exception is com.fasterxml.Hymanson.databind.JsonMappingException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.outbrain.images.beans.FileUploadBean["file"]->org.springframework.web.multipart.commons.CommonsMultipartFile["fileItem"]->org.apache.commons.fileupload.disk.DiskFileItem["inputStream"]->java.io.FileInputStream["fd"]) at org.springframework.http.converter.json.MappingHymanson2HttpMessageConverter.writeInternal
org.springframework.http.converter.HttpMessageNotWritableException:
无法编写 JSON: No serializer found for class java.io.FileDescriptor 并且没有发现创建 BeanSerializer 的属性(为了避免异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS))(通过参考链:com.outbrain.images.beans.FileUploadBean["file "]->org.springframework.web.multipart.commons.CommonsMultipartFile["fileItem"]->org.apache.commons.fileupload.disk.DiskFileItem["inputStream"]->java.io.FileInputStream["fd"] ); 嵌套异常是 com.fasterxml.Hymanson.databind.JsonMappingException: No serializer found for class java.io.FileDescriptor 并且没有发现创建 BeanSerializer 的属性(为了避免异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS))(通过参考链:com.outbrain。 images.beans.FileUploadBean["文件"
How can I make this request work?
我怎样才能使这个请求工作?
采纳答案by Avi
Well, after some struggling this is how I solved it. That's what I did in the second controller:
好吧,经过一番挣扎,这就是我解决的方法。这就是我在第二个控制器中所做的:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody
ResponseEntity<byte[]> uploadImage(final FileUploadBean fileUploadBean) throws Exception {
File file = null;
try {
final MultiValueMap<String, Object> requestParts = new LinkedMultiValueMap<>();
final String tmpImageFileName = IMAGE_TMP_DIR + fileUploadBean.getFile().getOriginalFilename();
file = new File(tmpImageFileName);
fileUploadBean.getFile().transferTo(file);
requestParts.add("file", new FileSystemResource(tmpImageFileName));
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "multipart/form-data"); // Sending it like the client-form sends it
ResponseEntity<byte[]> response = restTemplate.exchange(ImageUrlUtils.getUploadUrl(), HttpMethod.POST, new HttpEntity<>(requestParts, headers),
byte[].class);
return new ResponseEntity<>(response.getBody(), response.getStatusCode());
} catch (Exception ex) {
return new ResponseEntity<>((ex.getMessage).getBytes("UTF-8"),
HttpStatus.INTERNAL_SERVER_ERROR);
} finally {
if (file != null && file.exists()) {
file.delete();
}
}
}
回答by Сергей Сенько
I debug previous answer, and found this solution without save file to file system
我调试了以前的答案,发现这个解决方案没有将文件保存到文件系统
@PostMapping(value = "/upload")
public ResponseEntity<Object> upload(MultipartHttpServletRequest request) throws Exception {
final MultiValueMap<String, Object> requestParts = new LinkedMultiValueMap<>();
request.getParameterMap().forEach((name, value) -> requestParts.addAll(name, asList(value)));
request.getMultiFileMap().forEach((name, value) -> {
List<Resource> resources = value.stream().map(MultipartFile::getResource).collect(toList());
requestParts.addAll(name, resources);
});
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestParts, request.getRequestHeaders());
return restTemplate.exchange(ImageUrlUtils.getUploadUrl() + "?" + request.getQueryString(),
request.getRequestMethod(), requestEntity, Object.class);
}