Jersey client to download and save file

32,784

Solution 1

I don't know if Jersey let's you simply respond with a file like you have here:

File download = new File("C://Data/Test/downloaded/empty.pdf");
ResponseBuilder response = Response.ok((Object)download);

You can certainly use a StreamingOutput response to send the file from the server, like this:

StreamingOutput stream = new StreamingOutput() {
    @Override
    public void write(OutputStream os) throws IOException,
    WebApplicationException {
        Writer writer = new BufferedWriter(new OutputStreamWriter(os));

        //@TODO read the file here and write to the writer

        writer.flush();
    }
};

return Response.ok(stream).build();

and your client would expect to read a stream and put it in a file:

InputStream in = response.getEntityInputStream();
if (in != null) {
    File f = new File("C://Data/test/downloaded/testnew.pdf");

    //@TODO copy the in stream to the file f

    System.out.println("Result size:" + f.length() + " written to " + f.getPath());
}

Solution 2

For folks still looking for a solution, here is the complete code on how to save jaxrs response to a File.

public void downloadClient(){
    Client client = ClientBuilder.newClient();
    WebTarget target = client.target("http://localhost:7070/upload-0.0.1-SNAPSHOT/rest/files/download");

    Response resp = target
      .request("application/pdf,image/jpeg,application/xml,application/vnd.ms-excel")
      .get();

    if(resp.getStatus() == Response.Status.OK.getStatusCode())
    {
        InputStream is = resp.readEntity(InputStream.class);
        fetchFeed(is); 
        //fetchFeedAnotherWay(is) //use for Java 7
        IOUtils.closeQuietly(is);
        System.out.println("the file details after call:"+downloadfile.getAbsolutePath()+", size is "+downloadfile.length());
    } 
    else{
        throw new WebApplicationException("Http Call failed. response code is"+resp.getStatus()+". Error reported is"+resp.getStatusInfo());
    }
}
/**
* Store contents of file from response to local disk using java 7 
* java.nio.file.Files
*/
private void fetchFeed(InputStream is){
    File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");  
    byte[] byteArray = IOUtils.toByteArray(is);
    FileOutputStream fos = new FileOutputStream(downloadfile);
    fos.write(byteArray);
    fos.flush();
    fos.close();
}

/**
* Alternate way to Store contents of file from response to local disk using
* java 7, java.nio.file.Files
*/
private void fetchFeedAnotherWay(InputStream is){
    File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");  
    Files.copy(is, downloadfile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}

Solution 3

This sample code below may help you.

https://stackoverflow.com/a/32253028/15789

This is a JAX RS rest service, and test client. It reads bytes from a file and uploads the bytes to the REST service. The REST service zips the bytes and sends it back as bytes to the client. The client reads the bytes and saves the zipped file. I had posted this as a response to another thread.

Solution 4

Here's another way of doing it using Files.copy().

    private long downloadReport(String url){

            long bytesCopied = 0;
            Path out = Paths.get(this.fileInfo.getLocalPath());

            try {

                 WebTarget webTarget = restClient.getClient().target(url);
                 Invocation.Builder invocationBuilder = webTarget.request(MediaType.TEXT_PLAIN_TYPE);

                 Response response = invocationBuilder.get();

                 if (response.getStatus() != 200) {
                    System.out.println("HTTP status " response.getStatus());
                    return bytesCopied;
                 }

                 InputStream in = response.readEntity( InputStream.class );
                 bytesCopied = Files.copy(in, out, REPLACE_EXISTING);

                 in.close();

            } catch( IOException e ){
                 System.out.println(e.getMessage());
            }

            return bytesCopied;
     }
Share:
32,784
cxyz
Author by

cxyz

Updated on July 30, 2022

Comments

  • cxyz
    cxyz almost 2 years

    I Am new to jersey/JAX-RS implementation. Please find below my jersey client code to download file:

     Client client = Client.create();
     WebResource wr = client.resource("http://localhost:7070/upload-0.0.1-SNAPSHOT/rest/files/download");
     Builder wb=wr.accept("application/json,application/pdf,text/plain,image/jpeg,application/xml,application/vnd.ms-excel");
     ClientResponse clientResponse= wr.get(ClientResponse.class);
     System.out.println(clientResponse.getStatus());
     File res= clientResponse.getEntity(File.class);
     File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");  
     res.renameTo(downloadfile);
     FileWriter fr = new FileWriter(res);
     fr.flush();
    

    My Server side code is :

    @Path("/download")
        @GET
        @Produces({"application/pdf","text/plain","image/jpeg","application/xml","application/vnd.ms-excel"})
        public Response getFile()
        {
    
            File download = new File("C://Data/Test/downloaded/empty.pdf");
            ResponseBuilder response = Response.ok((Object)download);
            response.header("Content-Disposition", "attachment; filename=empty.pdf");
            return response.build();
        }
    

    In my client code i am getting response as 200 OK,but i am unable to save my file on hard disk In the below line i am mentioning the path and location where the files need to be saved. Not sure whats going wrong here,any help would be appreciated.Thanks in advance!!

    File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");
    
  • spr
    spr over 7 years
    Is it possible to do with @POST instead of @GET?
  • Paul Jowett
    Paul Jowett about 7 years
    It certainly is. To a large degree they are interchangeable. I prefer post usually because the body can be secured and parameters are not visible (where they should not be visible).