隧道MultipartFile

时间:2014-03-25 09:39:15

标签: java spring spring-mvc multipart

我有一个spring控制器,它接受FileUploadBean上名为POST的类。控制器方法如下所示:

第一个控制器

@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<byte[]> uploadFile(final FileUploadBean fileUploadBean) throws IOException {
   // Some code that works fine here
} 

其中一个FileUploadBean属性的类型为MultipartFile

现在,我尝试添加某种包装控制器(将在另一台服务器上运行),该控制器也接受FileUploadBean并将请求转发给第一个控制器:

第二个(包装器)控制器

@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;
}

当我将请求发送到第一个控制器时,我得到:

org.springframework.http.converter.HttpMessageNotWritableException:
     

无法编写JSON:没有为类找到序列化程序   java.io.FileDescriptor并没有发现要创建的属性   BeanSerializer(避免异常,禁用   SerializationFeature.FAIL_ON_EMPTY_BEANS))(通过参考链:   com.outbrain.images.beans.FileUploadBean [&#34;文件&#34;] - &GT; org.springframework.web.multipart.commons.CommonsMultipartFile [&#34;的FileItem&#34;] - &GT; org.apache。 commons.fileupload.disk.DiskFileItem [&#34;的inputStream&#34;] - &GT; java.io.FileInputStream中[&#34; FD&#34;]);   嵌套异常是   com.fasterxml.jackson.databind.JsonMappingException:没有序列化程序   找到类java.io.FileDescriptor并且没有发现属性   创建BeanSerializer(以避免异常,禁用   SerializationFeature.FAIL_ON_EMPTY_BEANS))(通过参考链:   com.outbrain.images.beans.FileUploadBean [&#34;文件&#34;] - &GT; org.springframework.web.multipart.commons.CommonsMultipartFile [&#34;的FileItem&#34;] - &GT; org.apache。 commons.fileupload.disk.DiskFileItem [&#34;的inputStream&#34;] - &GT; java.io.FileInputStream中[&#34; FD&#34;])         在org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal

如何使此请求有效?

2 个答案:

答案 0 :(得分:8)

嗯,经过一番挣扎,这就是我解决它的方法。这就是我在第二个控制器中所做的:

@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();
    }
  }
}

答案 1 :(得分:0)

我调试了先前的答案,并发现此解决方案没有将文件保存到文件系统

    @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);

}