Tunneling MultipartFile
Solution 1
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();
}
}
}
Solution 2
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);
}
Avi
Updated on June 07, 2022Comments
-
Avi over 1 year
I have a
spring
controller that accepts a class namedFileUploadBean
onPOST
. The controller method looks like that: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 typeMultipartFile
.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: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.jackson.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.MappingJackson2HttpMessageConverter.writeInternal
How can I make this request work?
-
Avi almost 8 years@Ranjeet - I'm glad to know that :)
-
Avi over 7 years@SumeetSharma - great to hear!
-
Federico about 4 yearsThanks for this, took me a good while until I saw this approach