20

I am creating POC for RESTFUL Web service using Spring 4.0. It is working fine if we pass only String or any other basic dataype.

@RequestMapping(value="/upload/file", method=RequestMapping.post)
public String uploadFile(@RequestParam("fileName", required=false) String fileName){
    logger.info("initialization of object");
    //----------------------------------------

     System.out.Println("name of File : " + fileName);  

    //----------------------------------------
}

This works fine. but If I want to pass byte stream or File Object to function, How can i write this function having these parameters? and How can I write Client having provision of passing byte stream?

@RequestMapping(value="/upload/file", method=RequestMapping.post)
public String uploadFile(@RequestParam("file", required=false) byte [] fileName){
     //---------------------
     // 
}

I tried this code but getting 415 Error.

@RequestMapping(value = "/upload/file", method = RequestMethod.POST, consumes="multipart/form-data")
public @ResponseBody String uploadFileContentFromBytes(@RequestBody MultipartFormDataInput input,  Model model) {
    logger.info("Get Content. "); 
  //------------
   }  

Client Code - Using apache HttpClient

private static void executeClient() {
    HttpClient client = new DefaultHttpClient();
    HttpPost postReqeust = new HttpPost(SERVER_URI + "/file");

    try{
        // Set Various Attributes
        MultipartEntity multipartEntity = new MultipartEntity();
        multipartEntity.addPart("fileType" , new StringBody("DOCX"));

        FileBody fileBody = new FileBody(new File("D:\\demo.docx"), "application/octect-stream");
        // prepare payload
        multipartEntity.addPart("attachment", fileBody);

        //Set to request body
        postReqeust.setEntity(multipartEntity);

        HttpResponse response = client.execute(postReqeust) ;

        //Verify response if any
        if (response != null)
        {
            System.out.println(response.getStatusLine().getStatusCode());
        }

    }
    catch(Exception ex){
        ex.printStackTrace();
    }
Morez
  • 2,048
  • 5
  • 36
  • 49
  • From the server point of view, it will receive a `MultipartFile`. From the HTTP point of view, it will transport `multipart/form-data`. And from the client point of view ... well it will depend on the client library ... – Serge Ballesta Sep 17 '14 at 09:45
  • IMHO, you should not use `@RequestBody` annotation when using `multipart/form-data`, but you should look at Spring Reference Manual to see how to configure an application to process file upload. – Serge Ballesta Sep 17 '14 at 10:09
  • @serge : I have tried this but facing 415 error. please suggest me good reference links. – Morez Sep 17 '14 at 10:11
  • @SergeBallesta : `@RequestParam` I used , i got 500 error. I guess it would work if I integrate with particular html form, then it works. otherwise it may not work. `@RequestParam(value="path") File file` I may be wrong. – Morez Sep 17 '14 at 10:22
  • 1
    You could find examples for file upload using Spring in Spring Reference Manual or in StackOverflow : (http://stackoverflow.com/questions/25286860/uploading-image-using-springmvc-4-0-multipart/25289820) or (http://http://stackoverflow.com/questions/25460779/converting-validating-csv-file-upload-in-spring-mvc/25463163) – Serge Ballesta Sep 17 '14 at 13:02
  • What does your request look like? – a better oliver Sep 17 '14 at 13:53

2 Answers2

35

You can create your rest service like below.

@RequestMapping(value="/upload", method=RequestMethod.POST)
    public @ResponseBody String handleFileUpload( 
            @RequestParam("file") MultipartFile file){
            String name = "test11";
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = 
                        new BufferedOutputStream(new FileOutputStream(new File(name + "-uploaded")));
                stream.write(bytes);
                stream.close();
                return "You successfully uploaded " + name + " into " + name + "-uploaded !";
            } catch (Exception e) {
                return "You failed to upload " + name + " => " + e.getMessage();
            }
        } else {
            return "You failed to upload " + name + " because the file was empty.";
        }
    }

And for the client side do like below.

import java.io.File;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;


public class Test {
  public static void main(String[] args) throws Exception {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

    HttpPost httppost = new HttpPost("http://localhost:8080/upload");
    File file = new File("C:\\Users\\Kamal\\Desktop\\PDFServlet1.pdf");

    MultipartEntity mpEntity = new MultipartEntity();
    ContentBody cbFile = new FileBody(file, "multipart/form-data");
    mpEntity.addPart("file", cbFile);


    httppost.setEntity(mpEntity);
    System.out.println("executing request " + httppost.getRequestLine());
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity resEntity = response.getEntity();

    System.out.println(response.getStatusLine());
    if (resEntity != null) {
      System.out.println(EntityUtils.toString(resEntity));
    }
    if (resEntity != null) {
      resEntity.consumeContent();
    }

    httpclient.getConnectionManager().shutdown();
  }
}
dReAmEr
  • 6,986
  • 7
  • 36
  • 63
  • I tried this but again facing 500 error code. `java.lang.IllegalStateException: Current request is not of type [org.springframework.web.multipart.MultipartRequest]: org.apache.catalina.connector.RequestFacade@7de7432b` I have updated my question with Client code. I am very confused now. :( – Morez Sep 17 '14 at 17:11
  • What you are using at the client end? can you just provide some client code also,from where you are making request to this service? – dReAmEr Sep 17 '14 at 17:12
  • I have updated the question there you can find client code. I am using apache http client. – Morez Sep 17 '14 at 17:31
  • just updated the previous service code and also provided client side code to test,it's working for me!!! – dReAmEr Sep 17 '14 at 17:59
  • 1
    I tried this code. unfortunately its not working for me. getting this error. `Required MultipartFile parameter 'file' is not present

    descriptionThe request sent by the client was syntactically incorrect.`

    – Morez Sep 17 '14 at 19:14
  • what is your file name,that you are sending from client side like for me it is "file" ,it has to be added in MultiPartEntity object Ex.(in client side) :-- mpEntity.addPart("file", cbFile); this name should match with the @RequestParam("file") of the rest service. – dReAmEr Sep 18 '14 at 03:36
  • "file" only. I got your point but still it is showing me same error. does it require any other configuration in dispatcher servlet? – Morez Sep 18 '14 at 05:00
  • Server side code working perfectly. Just Chekced through Postman plugin in chrome. There is problem in Client i guess. – Morez Sep 18 '14 at 05:20
  • Its working now . I just removed `multipart/form-data ContentBody cbFile = new FileBody(file);` Thank you everyone – Morez Sep 18 '14 at 06:54
2

<bean id="multipartResolver"
 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

this code requred

  • Thank you for your suggestion. but it is not the problem at all. MultipartResolver Bean is already there. Kindly check the answer which I have accepted. – Morez Oct 28 '15 at 08:14
  • what the purpose of this script? – tree em Jan 25 '18 at 15:31