问题
I have two endpoints api which are /uploadand /redirect
/upload is where I directly upload the file. /redirect is where i receive the file and pass it to upload and get the JSON response from /upload.So below is my code:
package com.example;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class UserLogsController {
@Autowired
@Qualifier("restTemplateUserRegitration")
private RestTemplate restTemplateUserRegitration;
@Bean
public RestTemplate restTemplateUserRegitration() {
RestTemplateBuilder builderUserRegitration = new RestTemplateBuilder();
RestTemplate buildUserRegitration = builderUserRegitration.build();
return buildUserRegitration;
}
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody ResponseEntity<Map<String, Object>> handleFileUpload(
@RequestParam("file") MultipartFile file) {
String name = file.getName();
System.out.println(name);
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(new File("D:\\myfile.csv")));
stream.write(bytes);
stream.close();
JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
FeedBackResponse.setCode(100);
FeedBackResponse.setMessage("Successfully Updated Batch User List");
Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
FeedBackStatus.put("status", FeedBackResponse);
return ResponseEntity.ok(FeedBackStatus);
} catch (Exception e) {
JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
FeedBackResponse.setCode(100);
FeedBackResponse.setMessage(e.getMessage());
Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
FeedBackStatus.put("status", FeedBackResponse);
return ResponseEntity.ok(FeedBackStatus);
}
} else {
JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
FeedBackResponse.setCode(100);
FeedBackResponse.setMessage("Successfully Updated Batch User List");
Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
FeedBackStatus.put("status", FeedBackResponse);
return ResponseEntity.ok(FeedBackStatus);
}
}
@RequestMapping(value = "/redirect", produces = { MediaType.APPLICATION_JSON_VALUE }, method = RequestMethod.POST)
public ResponseEntity<?> registerBatchUser(@RequestParam("file") MultipartFile file) {
Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
FeedBackStatus = restTemplateUserRegitration.postForObject("http://localhost:8080/upload", file, Map.class);
return ResponseEntity.ok(FeedBackStatus);
}
}
The endpoint /upload works pretty much fine.But when i call /redirect it throws an error of
"exception": "org.springframework.http.converter.HttpMessageNotWritableException", "message": "Could not write JSON document: 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: org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile["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: org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile["inputStream"]->java.io.FileInputStream["fd"])",
I am not sure why is this occuring.Any help is appreciated.
回答1:
This made the trick
@RequestMapping(value = "/redirect", produces = { MediaType.APPLICATION_JSON_VALUE }, method = RequestMethod.POST)
public ResponseEntity<?> registerBatchUser(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(new File("D:\\myfileredirect.csv")));
stream.write(bytes);
stream.close();
} catch (Exception e) {
JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
FeedBackResponse.setCode(100);
FeedBackResponse.setMessage(e.getMessage());
Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
FeedBackStatus.put("status", FeedBackResponse);
return ResponseEntity.ok(FeedBackStatus);
}
MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
parameters.add("file", new FileSystemResource("D:\\myfileredirect.csv"));
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "multipart/form-data");
Map<String, Object> FeedBackStatus=new HashMap<String, Object>();
FeedBackStatus = restTemplateUserRegitration.exchange("http://localhost:8080/upload", HttpMethod.POST, new HttpEntity<MultiValueMap<String, Object>>(parameters, headers), Map.class).getBody();
return ResponseEntity.ok(FeedBackStatus);
}
So what I did was basically collected the file rewrite it and then conver to a MultiValueMap and send to the service.
回答2:
I get with the same problem, I used a temporally file instead of a File.
Path tempFile = Files.createTempFile(null, null);
Files.write(tempFile, multipartFile.getBytes());
File fileToSend = tempFile.toFile();
MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
parameters.add("file", new FileSystemResource(fileToSend));
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "multipart/form-data");
HttpEntity httpEntity = new HttpEntity<>(parameters, headers);
try {
restTemplate.exchange(apiUrl, HttpMethod.POST,
httpEntity, MyClazz.class);
} finally {
fileAEnviar.delete();
}
来源:https://stackoverflow.com/questions/47087037/how-to-send-a-multipart-file-to-a-service-from-another-service