web-dev-qa-db-ja.com

ファイルをダウンロードして保存するJerseyクライアント

私はジャージ/ JAX-RSの実装に不慣れです。ファイルをダウンロードするには、以下の私のジャージクライアントコードを見つけてください。

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

私のサーバーサイドコードは:

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

クライアントコードで200OKと応答しますが、ファイルをハードディスクに保存できません。次の行で、ファイルを保存する必要があるパスと場所について説明しています。ここで何がうまくいかないのかわからないので、助けていただければ幸いです。よろしくお願いします!

File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");
8
cxyz

ジャージーがあなたがここにあるようなファイルで単に応答することができるかどうかはわかりません:

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

あなたcan確かに、次のようにStreamingOutput応答を使用してサーバーからファイルを送信します。

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

クライアントは、ストリームを読み取ってファイルに入れることを期待します。

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());
}
5
Paul Jowett

まだ解決策を探している人のために、jaxrsの応答をファイルに保存する方法に関する完全なコードを以下に示します。

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);
}
5
pNut

以下のサンプルコードが役立つ場合があります。

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

これはJAXRS RESTサービスであり、テストクライアントです。ファイルからバイトを読み取り、そのバイトをRESTサービスにアップロードします。RESTサービスはバイトを圧縮し、バイトとしてクライアントに送り返します。クライアントはバイトを読み取り、zipファイルを保存します。これを別のスレッドへの応答として投稿しました。

2

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;
     }
1