4

I am creating a REST service using Spring 4's rest controller and testing with Spring's RestTemplate.

I would like to accept a request to create a new file (POST).

The concept of a file in my system contains two parts - (1) Metadata, (2) Content. Therefore I have defined my rest controller to accept a MultipartHttpServletRequest. I want to pull the metadata map from one part and a file input stream from the second part, but I'm not sure how to make this work.

Having an input stream instead of the entire file in the request is important because the files may be very large and I don't want to stress the network by making users send giant http requests with all of the file data.

Below I have a non-working implementation of my rest controller method and my test I use to send a test Http Request. When I run the below code I get a 500 Server Error exception because I believe that the request isn't matching correctly to how I have configured the RestController.

I have tried, in the controller, to make the @RequestParam's generic Objects instead of a Map and InputStream. This will run without a 500 exception, but then the objects are then interpreted as Strings, and that's not what I want (this would be okay for dealing with the metadata, but I want an InputStream for the file!).

Create a request:

public void createAndSendRequest() throws IOException {
   MultiValueMap<String,Object> requestMap = new LinkedMultiValueMap<String, Object>();
   url = "http:/my.domain/someService/document";
   method = HttpMethod.POST;
   returnType = String.class;

   // add metadata to the request
   Map<String, String> metadata = new HashMap<>();
   metadata.put("somedata1", "alpha");
   metadata.put("somedata2", "beta");
   metadata.put("somedata3", "gamma");
   requestMap.add("metadata", metadata);

   // add the file to the request (as a stream?)
   URL fileUrl = this.getClass().getClassLoader().getResource("test.txt");
   File file = new File(fileUrl.getFile());
   InputStream stream = new FileInputStream(file);
   InputStreamResource resource = new InputStreamResource(stream);
   requestMap.add("file", resource);

   response = restTemplate.exchange(url, method, new HttpEntity<Object>(requestMap, headers), returnType);
   handleResponse(response);
}

Rest Controller method to handle the request:

    @RequestMapping(value = "/document", method = RequestMethod.POST)
    public ResponseEntity<String> createDocument(MultipartHttpServletRequest request,
                @RequestParam("file") InputStream fileStream,
                @RequestParam("metadata") Map metadata) throws Exception {

       // do some file stream work
       int ch;
       ch = fileStream.read();
       while (ch != -1) {
           System.out.println((char) ch);
           ch = fileStream.read();
       }

       // do application stuff

       return new ResponseEntity(HttpStatus.CREATED);
    }
Luke
  • 470
  • 6
  • 10
  • Read [this](http://stackoverflow.com/questions/26964688/multipart-file-upload-using-spring-rest-template-spring-web-mvc) and [this](http://stackoverflow.com/questions/20926446/rest-fileupload-in-spring-controller-using-multipart-form-data) – Bond - Java Bond Oct 15 '15 at 14:38

0 Answers0