Presta atención porque en esta sección hallarás la solución que buscas.Este escrito ha sido aprobado por nuestros expertos para asegurar la calidad y exactitud de nuestro post.
Solución:
Lectura de todo el archivo en un ByteArrayResource
puede ser un problema de consumo de memoria con archivos grandes.
Puede cargar un archivo proxy en un controlador spring mvc usando un InputStreamResource
:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity> uploadImages(@RequestPart("images") final MultipartFile[] files) throws IOException
LinkedMultiValueMap map = new LinkedMultiValueMap<>();
String response;
HttpStatus httpStatus = HttpStatus.CREATED;
try
for (MultipartFile file : files)
if (!file.isEmpty())
map.add("images", new MultipartInputStreamFileResource(file.getInputStream(), file.getOriginalFilename()));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
String url = "http://example.com/upload";
HttpEntity> requestEntity = new HttpEntity<>(map, headers);
response = restTemplate.postForObject(url, requestEntity, String.class);
catch (HttpStatusCodeException e)
httpStatus = HttpStatus.valueOf(e.getStatusCode().value());
response = e.getResponseBodyAsString();
catch (Exception e)
httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
response = e.getMessage();
return new ResponseEntity<>(response, httpStatus);
class MultipartInputStreamFileResource extends InputStreamResource
private final String filename;
MultipartInputStreamFileResource(InputStream inputStream, String filename)
super(inputStream);
this.filename = filename;
@Override
public String getFilename()
return this.filename;
@Override
public long contentLength() throws IOException
return -1; // we do not want to generally read the whole stream into memory ...
Obtiene la excepción porque ninguno de los MessageConverters predeterminados de RestTemplate sabe cómo serializar el InputStream contenido en el archivo MultipartFile. Al enviar objetos a través de RestTemplate, en la mayoría de los casos desea enviar POJO. Puede solucionar esto agregando los bytes de MultipartFile a MultiValueMap en lugar del propio MultipartFile.
Creo que también hay algo mal con su parte de servlet. Por ejemplo
File file1 = (File) req.getAttribute("userfile1");
siempre debe volver nullya que el método getAttribute de ServletRequest no devuelve parámetros de solicitud/formulario, pero attributes establecido por el contexto del servlet. ¿Está seguro de que realmente está funcionando con su ejemplo de curl?
Aquí hay un ejemplo de un método Spring MVC que reenvía un archivo a un servlet:
Servlet (aunque lo probé ejecutándose en un contenedor Spring MVC), adaptado de aquí:
@RequestMapping("/pi")
private void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
final String path = request.getParameter("destination");
final Part filePart = request.getPart("file");
final String fileName = request.getParameter("filename");
OutputStream out = null;
InputStream fileContent = null;
final PrintWriter writer = response.getWriter();
try
out = new FileOutputStream(new File(path + File.separator
+ fileName));
fileContent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = fileContent.read(bytes)) != -1)
out.write(bytes, 0, read);
writer.println("New file " + fileName + " created at " + path);
catch (FileNotFoundException fne)
writer.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent "
+ "location.");
writer.println("
ERROR: " + fne.getMessage());
finally
if (out != null)
out.close();
if (fileContent != null)
fileContent.close();
if (writer != null)
writer.close();
Método Spring MVC:
@ResponseBody
@RequestMapping(value="/upload/", method=RequestMethod.POST,
produces = "text/plain")
public String uploadFile(MultipartHttpServletRequest request)
throws IOException
Iterator itr = request.getFileNames();
MultipartFile file = request.getFile(itr.next());
MultiValueMap parts =
new LinkedMultiValueMap();
parts.add("file", new ByteArrayResource(file.getBytes()));
parts.add("filename", file.getOriginalFilename());
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity> requestEntity =
new HttpEntity>(parts, headers);
// file upload path on destination server
parts.add("destination", "./");
ResponseEntity response =
restTemplate.exchange("http://localhost:8080/pi",
HttpMethod.POST, requestEntity, String.class);
if (response != null && !response.getBody().trim().equals(""))
return response.getBody();
return "error";
Usando estos, puedo cargar con éxito un archivo a través del método MVC al servlet mediante el siguiente curl:
curl --form [email protected] localhost:8080/upload/
Desde la versión 5.1, Spring Framework se envía con su propio Resource
implementación para MultipartFile
s. Por lo tanto, puede simplificar la respuesta de Lorenzo eliminando el MultipartInputStreamFileResource
class y llenando el mapa de la siguiente manera:
[...]
for (MultipartFile file : files)
if (!file.isEmpty())
map.add("images", file.getResource());
[...]
Eres capaz de auxiliar nuestra tarea añadiendo un comentario y dejando una puntuación te estamos agradecidos.