android - Retrofit 2 file down/upload -
i'm trying down/upload file retrofit 2 can't find tutorials examples on how so. code downloading is:
@get("documents/checkout") public call<file> checkout(@query(value = "documenturl") string documenturl, @query(value = "accesstoken") string accesstoken, @query(value = "readonly") boolean readonly);
and
call<file> call = retrofitsingleton.getinstance(serveraddress) .checkout(document.getcontenturl(), apitoken, readonly[i]); call.enqueue(new callback<file>() { @override public void onresponse(response<file> response, retrofit retrofit) { string filename = document.getfilename(); try { system.out.println(response.body()); long filelength = response.body().length(); inputstream input = new fileinputstream(response.body()); file path = environment.getexternalstoragedirectory(); file file = new file(path, filename); bufferedoutputstream output = new bufferedoutputstream( new fileoutputstream(file)); byte data[] = new byte[1024]; long total = 0; int count; while ((count = input.read(data)) != -1) { total += count; output.write(data, 0, count); } output.flush(); output.close(); } catch (ioexception e) { string logtag = "temptag"; log.e(logtag, "error while writing file!"); log.e(logtag, e.tostring()); } } @override public void onfailure(throwable t) { // todo: error handling system.out.println(t.tostring()); } });
i've tried call , call nothing seems work.
the server-side code writes file's bytes httpservletresponse's output stream after setting headers , mime type correctly.
what doing wrong?
finally, upload code:
@multipart @post("documents/checkin") public call<string> checkin(@query(value = "documentid") string documentid, @query(value = "name") string filename, @query(value = "accesstoken") string accesstoken, @part("file") requestbody file);
and
requestbody requestbody = requestbody.create(mediatype.parse(document.getmimetype()), file); call<string> call = retrofitsingleton.getinstance(serveraddress).checkin(documentid, document.getfilename(), apitoken, requestbody); call.enqueue(new callback<string>() { @override public void onresponse(response<string> response, retrofit retrofit) { system.out.println(response.body()); } @override public void onfailure(throwable t) { system.out.println(t.tostring()); } });
thanks!
edit:
after answer, downloading yields corrupted file (without @streaming), uploading doesn't well. when use above code, server returns 400 error. after changing to
requestbody requestbody = requestbody.create(mediatype.parse(document.getmimetype()), file); multipartbuilder multipartbuilder = new multipartbuilder(); multipartbuilder.addformdatapart("file", document.getfilename(), requestbody); call<string> call = retrofitsingleton.getinstance(serveraddress).checkin(documentid, document.getfilename(), apitoken, multipartbuilder.build());
, request executes backend doesn't seem receive file.
backend code:
@requestmapping(value = "/documents/checkin", method = requestmethod.post) public void checkindocument(@requestparam string documentid, @requestparam string name, @requestparam multipartfile file, @requestparam string accesstoken, httpservletresponse response)
what doing wrong? able use backend plain java apache httpclient:
multipartentitybuilder builder = multipartentitybuilder.create(); builder.setmode(httpmultipartmode.browser_compatible); builder.addbinarybody("file", new file("e:\\temp\\test.jpg")); httpentity httpentity = builder.build(); system.out.println("httpentity " + entityutils.tostring(httpentity.)); httppost httppost = new httppost(uri); httppost.setentity(httpentity);
edit v2
for interested, both up- , downloading work now: these solutions:
service:
@get("documents/checkout") public call<responsebody> checkout(@query(value = "documenturl") string documenturl, @query(value = "accesstoken") string accesstoken, @query(value = "readonly") boolean readonly); @multipart @post("documents/checkin") public call<string> checkin(@query(value = "documentid") string documentid, @query(value = "name") string filename, @query(value = "accesstoken") string accesstoken, @part("file") requestbody file);
download code:
call<responsebody> call = retrofitsingleton.getinstance(serveraddress) .checkout(document.getcontenturl(), apitoken, readonly[i]); call.enqueue(new callback<responsebody>() { @override public void onresponse(response<responsebody> response, retrofit retrofit) { string filename = document.getfilename(); try { file path = environment.getexternalstoragedirectory(); file file = new file(path, filename); fileoutputstream fileoutputstream = new fileoutputstream(file); ioutils.write(response.body().bytes(), fileoutputstream); } catch (ioexception e) { log.e(logtag, "error while writing file!"); log.e(logtag, e.tostring()); } } @override public void onfailure(throwable t) { // todo: error handling system.out.println(t.tostring()); } });
upload code:
call<string> call = retrofitsingleton .getinstance(serveraddress).checkin(documentid, document.getfilename(), apitoken, multipartbuilder.build()); call.enqueue(new callback<string>() { @override public void onresponse(response<string> response, retrofit retrofit) { // handle response here } @override public void onfailure(throwable t) { // todo: error handling system.out.println("error"); system.out.println(t.tostring()); } });
for downloading, can use responsebody
return type --
@get("documents/checkout") @streaming public call<responsebody> checkout(@query("documenturl") string documenturl, @query("accesstoken") string accesstoken, @query("readonly") boolean readonly);
and can responsebody
input stream in call --
call<responsebody> call = retrofitsingleton.getinstance(serveraddress) .checkout(document.getcontenturl(), apitoken, readonly[i]); call.enqueue(new callback<responsebody>() { @override public void onresponse(response<responsebody> response, retrofit retrofit) { string filename = document.getfilename(); try { inputstream input = response.body().bytestream(); // rest of code
your upload looks okay @ first glance if server handles multipart messages correctly. working? if not, can explain failure mode? might able simplify not making multipart. remove @multipart
annotation , convert @path
@body
--
@post("documents/checkin") public call<string> checkin(@query("documentid") string documentid, @query("name") string filename, @query("accesstoken") string accesstoken, @body requestbody file);
Comments
Post a Comment