Sending Large Image in chunks - java

I am sending images from my android client to java jersey restful service and I succeded in doing that.But my issue is when I try to send large images say > 1MB its consumes more time so I like to send image in CHUNKS can anyone help me in doing this.How to send(POST) image stream in CHUNKS to server

references used :
server code & client call
server function name
/*** SERVER SIDE CODE****/
#POST
#Path("/upload/{attachmentName}")
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
public void uploadAttachment(
#PathParam("attachmentName") String attachmentName,
#FormParam("input") InputStream attachmentInputStream) {
InputStream content = request.getInputStream();
// do something better than this
OutputStream out = new FileOutputStream("content.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
// whatever processing you want here
out.write(buffer, 0, len);
}
out.close();
return Response.status(201).build();
}
/**********************************************/
/**
CLIENT SIDE CODE
**/
// .....
client.setChunkedEncodingSize(1024);
WebResource rootResource = client.resource("your-server-base-url");
File file = new File("your-file-path");
InputStream fileInStream = new FileInputStream(file);
String contentDisposition = "attachment; filename=\"" + file.getName() + "\"";
ClientResponse response = rootResource.path("attachment").path("upload").path("your-file-name")
.type(MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", contentDisposition)
.post(ClientResponse.class, fileInStream);
You should split the file in the client and restore part of the file in the server.
and after that you should merge the files together. Take a look at split /merge file on coderanch
Enjoy ! :)

Another path is available, if you don't want to code too much consider using :
file upload apache that is great ! :)

Related

How send the http post request with DataOutPutStream properly so server can handle it

I wish somebody tell me what is the different of just write a file and a file with another kind of bytes.
server using, python3 flask
I think maybe the android retrofit etc useful, but I would like to try with the classic method, HTTPUrlConnection
So i successfully sending just one or multi-parameter of string to the server.
I also successfully just by sending a file to the server.
- my file will just 5-second audio or video mp4 that creates from real android.
When i tried just two, param and a list of byte, len(list) = 2, i can get back my sent file, but the concat style of the bytes just could not acheive it.
but when I combine both of it, i found out that when the file is chopped as multi-part, the file just could not recover.
I know delimeter is useful, I tried with a string of "--------------" to split it in server-side.
list= request.data.split(b"------------------------------")
newList= list[1:]
data = b""
for part in newList:
data += part
how i recover the file (python)
def createAudioFromDataReceived(fileName, data):
with open(fileName, 'wb') as wfile:
wfile.write(data)
the basic code write to dataOutPutStream
public void writeFilesParamToDataOutputStream(HttpURLConnection conn, File file, String action) throws IOException {
byte[] buffer;
FileInputStream fileInputStream = new FileInputStream(file);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
buffer = new byte[1024 * 1024];
int length = 0;
while ( ( length = fileInputStream.read( buffer ) ) > 0 ) {
dos.write(buffer, 0, length);
}
dos.flush();
fileInputStream.close();
dos.close();
}
to add extra line to the dataOutputStream
//Bytes
byte[] bytes = "toSend".getBytes();
dos.write(bytes);
dos.write("------------------------------");
ops, reference are seen before
roughly this kind How to send data from server to Android?
i could not imagine the byte got alot of "-" and need "/r/n" ...
delimiter should be some thing like
String delimiter = "--aaWEdFXvDF--" + "\r\n";

Jersey client downloads content partially

I have a Java Jersey client with which I connect to a server and download an image like this:
WebTarget webTarget = client.target(url);
Response response = webTarget.request().get();
The client response is the following:
InboundJaxrsResponse{ClientResponse{method=GET, uri=resourceURL, status=200, reason=OK}}
When I try to parse the body as an InputStream like this to a file
InputStream imageInputStream = response.readEntity(InputStream.class);
OutputStream outputStream = new FileOutputStream(new File("test.jpg"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
The input stream breaks at ~7000bytes and the content never gets parsed totally.
I have no access to the image server, and if I try to access the URL of the image in the browser, it works and the image gets downloaded.
On top the server has a self signed SSL certificate which I registered to my java keystore, can that be also part of the issue?

Java: Binary File Upload using Restlet + Apache Commons FileUpload

I have a REST API with Restlet 2.3 and need to implement a file-uploading functionality to it.
The problem is that, when someone uploads a file using a POST (with a multipart/form-data Content-Type), the file reaches the server with another encoding.
To test this, I printed the contents of the original file in a Unix Terminal and then printed it again before parsing the requet with Apache Commons FileUpload (with almost the same code of this example http://restlet.com/technical-resources/restlet-framework/guide/2.2/extensions/fileupload). Both printed contents are very similar, but the original file has less characters, so i assume that my Java server is using the wrong encoding to interpret the file.
The file I sent is a PNG image. With text files the server works perfectly, but when I send photos or any binary file, the problem appears.
I don't know how you exactly did to check the received content. First you should check the content type that is used for your file part within the content of your multipart request. You should have something like that for a JPG image:
-----------------------------75956101888331271337088331
Content-Disposition: form-data; name="fileToUpload"; filename="myimage.jpg"
Content-Type: image/jpeg
Secondly, I don't know how you actually write the content you received. Apache Commons IO brings an utility method IOUtils.copy that provides a simple solution to write in an OutputStream the content received from an InputStream. See how ti can be used in your context:
while (fileIterator.hasNext()) {
FileItemStream fi = fileIterator.next();
if (fi.getFieldName().equals("fileToUpload")) {
FileOutputStream fos = new FileOutputStream(
"output"+File.separator+fi.getFieldName());
IOUtils.copy(fi.openStream(), fos);
fos.close();
}
}
IMO, the encoding aspect only applies for text not for binary content.
Hope it helps,
Thierry
I actually solved it by using Google's ByteStreams class:
while (fileIterator.hasNext()) {
FileItemStream fi = fileIterator.next();
if (fi.getFieldName().equals(FILE_TO_UPLOAD)) {
byte[] byteArray = ByteStreams.toByteArray(fi.openStream());
result = new String(byteArray,Charset.forName("ISO-8859-1"));
}
}
I had the similar problem when uploading the image file. This is how I fixed. The problem was in my case the data read from the inputstream. As it is reading from a socket no guarantee that you will have the full buffer of your array filled. Therefore you should check your data size before writing it to the outputbuffer/file. Here is my code hope it helps. Also available in repository https://github.com/esabilbulbul/java-servlet-fileupload/blob/master/README.md
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
upload.setHeaderEncoding("UTF-8");
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext())
{
FileItemStream item = iter.next();
String name = item.getFieldName();
//InputStream attachmentStream = item.openStream();
//byte[] attachmentBytes = ByteStreams.toByteArray(attachmentStream);
//InputStream stream = item.getInputStream();
InputStream stream = item.openStream();
if (item.isFormField())
{
//System.out.println("Form field " + name + " with value " + Streams.asString(stream) + " detected.");
}
else
{
System.out.println("File field " + name + " with file name "+ item.getName() + " detected.");
// Process the input stream
FileOutputStream fout= new FileOutputStream ("c:\\" + item.getName());
BufferedOutputStream bout= new BufferedOutputStream (fout);
BufferedInputStream bin= new BufferedInputStream(stream);
byte buf[] = new byte[2048];
int len=0;
while ((len = bin.read(buf)) > 0)//((bin.read(buf)) != -1)
{
bout.write(buf, 0, len);
if (len<2048)
len = len;
}
bout.close();
bin.close();
}
}

Downloading files using servlets

hi i have tried the following java codes which works fine if i use them as a java application but when i use the same code in my servlet page they dont work means i am not able to download the files. Please suggest what changes should i do so that i can download the file using Servlets.
a.
java.io.BufferedInputStream in = new java.io.BufferedInputStream(new java.net.URL("http://169.254.174.150:8084/WebApplication1/files/check.txt").openStream());
File f1 = new File("D:\\a.txt");
java.io.FileOutputStream fos = new java.io.FileOutputStream(f1);
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
byte data[] = new byte[1024];
while (in.read(data, 0, 1024) >= 0) {
bout.write(data);
}
bout.close();
in.close();
}
b. http://www.javabeat.net/examples/2012/04/13/download-file-from-http-https-server-using-java/
One of the older JavaBeat examples like the one you specified can be found here
I found other solutions too but this seems to be the most comprehensive.
Couple of things, insetad of writing it to a file try wrting the data directly to the responce. Before writing data you will have to set the following parameters to the responce
//byte[] filedata = ; intialize your file contents
String filename = "a.txt";
// set the header information in the response.
res.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\";");
res.setContentType("application/x-unknown");
ByteArrayInputStream byteStream = new ByteArrayInputStream(filedata);
BufferedInputStream bufStream = new BufferedInputStream(byteStream);
ServletOutputStream responseOutputStream = res.getOutputStream();
int data = bufStream.read();
while (data != -1)
{
responseOutputStream.write(data);
data = bufStream.read();
}
bufStream.close();
responseOutputStream.close();
where res is a HttpServletResponse object. After this you can write data to responseOutputStream.

how to decompress http response?

Can any one of you solve this problem !
Problem Description:
i have received content-encoding: gzip header from http web-server.
now i want to decode the content but when i use GZIP classes from jdk 1.6.12, it gives null.
does it means that contents are not in gzip format ? or are there some another classes for decompress http response content?
Sample Code:
System.out.println("Reading InputStream");
InputStream in = httpuc.getInputStream();// httpuc is an object of httpurlconnection<br>
System.out.println("Before reading GZIP inputstream");
System.out.println(in);
GZIPInputStream gin = new GZIPInputStream(in));
System.out.println("After reading GZIP inputstream");
Output:
Reading InputStream
Before reading GZIP inputstream
sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#8acf6e
null
I have found one error in code, but don't able to understand it properly. what does it indicates.
Error ! java.io.EOFException
Thanks
I think you should have a look at HTTPClient, which will handle a lot of the HTTP issues for you. In particular, it allows access to the response body, which may be gzipped, and then you simply feed that through a GZIPInputStream
e.g.
Header hce = postMethod.getResponseHeader("Content-Encoding");
InputStream in = null;
if(null != hce)
{
if(hce.getValue().equals(GZIP)) {
in = new GZIPInputStream(postMethod.getResponseBodyAsStream());
}
// etc...
I second Brian's suggestion. Whenever u need to deal with getting/posting stuff via HTTP don't bother with low-level access use the Apache HTTP client.
InputStream is = con.getInputStream();
InputStream bodyStream = new GZIPInputStream(is);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int length;
while ((length = bodyStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
String body = new String(outStream.toByteArray(), "UTF-8");

Categories

Resources