How to send Multipart form data with restTemplate Spring-mvc

后端 未结 3 1026
时光说笑
时光说笑 2020-12-14 16:22

I am trying to upload a file with RestTemplate to Raspberry Pi with Jetty. On Pi there is a servlet running:



        
3条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-14 17:05

    You are getting the exception because none of RestTemplate's default MessageConverters know how to serialize the InputStream contained by the MultipartFile file. When sending objects via RestTemplate, in most cases you want to send POJOs. You can fix this by adding the bytes of the MultipartFile to the MultiValueMap instead of the MultipartFile itself.

    I think there is also something wrong with your servlet part. For instance

    File file1 = (File) req.getAttribute("userfile1");
    

    should always return null, as ServletRequest's getAttribute method does not return request/form parameters but attributes set by the servlet context. Are you sure it is actually working with your curl example?

    Here is an example of a Spring MVC method forwarding a file to a servlet:

    Servlet (though I tested it running in a Spring MVC container), adapted from here:

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

    Spring MVC method:

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

    Using these I can succesfully upload a file through the MVC method to the servlet by the following curl:

    curl --form file=@test.dat localhost:8080/upload/
    

提交回复
热议问题