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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:57:40  来源:igfitidea点击:

Tunneling MultipartFile

javaspringspring-mvcmultipart

提问by Avi

I have a springcontroller that accepts a class named FileUploadBeanon POST. The controller method looks like that:

我有一个spring控制器,它接受一个名为FileUploadBeanon的类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 FileUploadBeanproperties 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 FileUploadBeanand 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);

}