I am attempting to have my android phone connect to my servlet and send it a certain image. The way I figured I would do this, is to use the copyPixelsToBuffer() function and then attempt to send this to the servlet through some output stream(similar to how I would do it in a normal stand alone java application). Will this way work? If so, what kind of stream do I use exactly? Should I just use DataOutputStream and just do something like the following:
ByteBuffer imgbuff;
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
bm.copyPixelsToBuffer(bm);
...code...
URLConnection sc = server.openConnection();
sc.setDoOutput(true);
DataOutputStream out = new DataOutputStream( sc.getOutputStream() );
out.write(imgbuff.array());
out.flush();
out.close();
Note: I understand that this may not be the proper way of connecting to a server using the Android OS but at the moment I'm working on just how to send the image, not the connection (unless this is relevant on how the image is sent).
If this is not a way you'd recommend sending the image to the servlet (I figured a byte buffer would be best but I could be wrong), how would you recommend this to be done?
Since a HttpServlet normally listens on HTTP requests, you'd like to use multipart/form-data encoding to send binary data over HTTP, instead of raw (unformatted) like that.
From the client side on, you can use URLConnection for this as outlined in this mini tutorial, but it's going to be pretty verbose. You can also use Apache HttpComponents Client for this. This adds however extra dependencies, I am not sure if you'd like to have that on Android.
Then, on the server side, you can use Apache Commons FileUpload to parse the items out of a multipart/form-data encoded request body. You can find a code example in this answer how the doPost() of the servlet should look like.
As to your code example: wrapping in the DataOutputStream is unnecessary. You aren't taking benefit of the DataOutputStream's facilities. You are just using write(byte[]) method which is already provided by the basic OutputStream as returned by URLConnection#getOutputStream(). Further, the Bitmap has a compress() method which you can use to compress it using a more standard and understandable format (PNG, JPG, etc) into an arbitrary OutputStream. E.g.
output = connection.getOutputStream();
// ...
bitmap.compress(CompressFormat.JPEG, 100, output);
Do this instead of output.write(bytes) as in your code.
Related
My application need to transfer multiple files to an http server (by opening OutputStream from HttpUrlConnection) but to avoid overhead of connection establishment we would like to use one connection only. Would this be feasible?
Note: The data is created in real time so that we cannot add them into one archive file and transfer with one shot.
Thanks for your advices!
You're over-optimizing. HttpURLConnection already does TCP connection pooling behind the scenes. Just use a new URL, HttpURLConnection, OutputStream, etc., per file.
The fact that you have to output more than one file does not prevent the fact that you can still use an archive format which can be created using your OutputStream, in real time; and zip is such a format.
The JDK has ZipOutputStream which can help you there; basically you can use it as such (code to set the HTTP headers not shown):
// out is your HttpUrlConnection's OutputStream
try (
final ZipOutputStream zout = new ZipOutputStream(out);
) {
addEntries(zout);
}
The addEntries() method would then create ZipEntry instances, one per file, and write the contents.
Try to use Apache HttpClient. It supports HTTP 1.1 keep-alive feature.
Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Fast read: http://en.wikipedia.org/wiki/HTTP_persistent_connection
Im working on an Web app using gwt and I generate a BufferedImg on the Serverside, which i want to be send to the Clientside. I have no Idea how to do that...
You can generate your image as a BufferedImage on your server side, and then pass it to client side with Remote Procedure Calls.
You have to implement:
Server side
ImageServiceImpl class which extends RemoteServiceServlet at your server side.
This class will genererate a BufferedImage:
File imagePath = new File(url);
BufferedImage image = ImageIO.read(imagePath);
You will send this image to your client side.
Client side
At you client side you have to create a synchronous ImageService interface, which extends RemoteService interface.
You must also create another client interface, an asynchronous one,(ImageServiceAsync) based on your original service interface. As described in the GWT Project
The nature of asynchronous method calls requires the caller to pass in a callback object that can be notified when an asynchronous call completes, since by definition the caller cannot be blocked until the call completes. For the same reason, asynchronous methods do not have return types; they generally return void. Should you wish to have more control over the state of a pending request, return Request instead. After an asynchronous call is made, all communication back to the caller is via the passed-in callback object.
Finally add your servlet to your web.xml
<servlet>
<servlet-name>ImageServiceImpl</servlet-name>
<servlet-class>
com.example.image.server.ImageServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServiceImpl</servlet-name>
<url-pattern>/com.example.image.Image/ImageService</url-pattern>
</servlet-mapping>
In order to send your image from server to client you have to follow 3 steps:
Instantiate the service interface using GWT.create().
Create an asynchronous callback object to be notified when the RPC has completed.
Make the call.
These are generic rules to follow, I propose this not as a final solution to your problem, but as a guide in order to have an idea how RPC is defined and working. RPC is little complicated at the beginning, but as soon as you understand the mechanism, you will be able to pass a variety of data from your server to your client side.
[EDIT]
In case of Image type, have in mind that in GWT, HTML Images are loaded via the SRC attribute in an IMG element. Passing an image from server to client via RPCT cannot be done directly, but by using a tricK:
Have the RPC call return a String of the image in Base 64.
In the onSuccess() method, use that result String as the argument for setUrl() (which
sets the SRC attribute).
You have to save the image as file in a "public" location and then on client side generate the URL to the image. Otherwise you can generate the image as servlet output for an HttpServlet.
You can't send the image to the client side directly.
You could use Base64 encoding to serialize your image and send it over the wire. You'll have to find a solution to decode it with GWT though. This might get you started How do I encode/decode short strings as Base64 using GWT?
I genearated my image as BufferedImage and transform it into ByteArrayOutputStream and return as follow..
public void downloadImage(final HttpServletRequest req,final HttpServletResponse res) throws Exception {
File imagePathFile = new File(url);
if (imagePathFile.exists()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage image = ImageIO.read(imagePathFile);
ImageIO.write(image, "jpg", baos);
StringBuffer sbFilename = new StringBuffer();
sbFilename.append("Image_");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sbFilename.append(sdf.format(new Date()));
sbFilename.append(".jpg");
StringBuffer sbContentDispValue = new StringBuffer();
sbContentDispValue.append("inline");
sbContentDispValue.append("; filename=");
sbContentDispValue.append(sbFilename);
res.setContentType("image/jpeg/jpg/png");
res.addHeader("Cache-Control", "max-age=30");
res.addHeader("Content-disposition", sbContentDispValue.toString());
res.setContentLength(baos.size());
ServletOutputStream os = res.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
}
}
To display static images stored on the server in a GWT client, simply do as follows:
Store images in your GWT MyApp/war/images folder.
Embed image name in an object text field. For example, if you have an object called 'Employee' with a bio field, embed text 'IMAGE: jane_doe.jpg'.
Your objects should be downloaded to the client using jason (typically in your EntryPointImpl.onModuleLoad();
Use regex to extract filename from text field.
Set String path="images/"+filename.
Create image object; e.g. Image img=new Image(path);
Style and size as desired.
GWT will retrieve images using HTTP GET.
I have a httpurlconnection code that is meant to post data to server. When I am trying to send small data it's ok but whene i try to send a base64 image string the string is not received properly at server. I have checked the base64 converted string from jpg and the encoding is ok. So, there is something wrong with the http process that's making the string corrupted. Initially I thought that probably it's the big images that's causing the problem but on using a very small image only transfers part of the image to server and the rest is corrupted.
Can somebody suggest me how can I send a base64 image string to server. My code is as below:
HttpURLConnection hpcon= (HttpURLConnection) Url.openConnection();
hpcon.setRequestMethod("POST");
hpcon.setConnectTimeout(5 * 1000);
hpcon.setDoOutput(true);
OutputStreamWriter osw= new OutputStreamWriter(hpcon.getOutputStream());
osw.write(data);
osw.close();
The data is something like:
key=YeP1r&nodeId=5&typeId=9&status=0&eventImage=imageString
Couldn't find a straight solution using HttpUrlConnection.
Used: httpClient from apache.
Actually pretty easy to use.
Last example multipart
I am decoding http packets.
And I faced a problem that chunk problem.
When I get a http packet it has a header and body.
When transefer-encoding is chunked I don't know what to do ?
Is there a useful API or class for dechunk the data in JAVA ?
And if someone , experienced about http decoding , please show me a way how to do this ?
Use a fullworthy HTTP client like Apache HttpComponents Client or just the Java SE provided java.net.URLConnection (mini tutorial here). Both handles it fully transparently and gives you a "normal" InputStream back. HttpClient in turn also comes with a ChunkedInputStream which you just have to decorate your InputStream with.
If you really insist in homegrowing a library for this, then I'd suggest to create a class like ChunkedInputStream extends InputStream and write logic accordingly. You can find more detail how to parse it in this Wikipedia article.
Apache HttpComponents
Oh, and if we are talking about the client side, HttpUrlConnection does this as well.
If you are looking for a simple API try Jodd Http library (http://jodd.org/doc/http.html).
It handles Chunked transfer encoding for you and you get the whole body as a string back.
From the docs:
HttpRequest httpRequest = HttpRequest.get("http://jodd.org");
HttpResponse response = httpRequest.send();
System.out.println(response);
Here is quick-and-dirty alternative that requires no dependency except Oracle JRE:
private static byte[] unchunk(byte[] content) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(content);
ChunkedInputStream cis = new ChunkedInputStream(bais, new HttpClient() {}, null);
return readFully(cis);
}
It uses the same sun.net.www.http.ChunkedInputStream as java.net.HttpURLConnection does behind the scene.
This implementation doesn't provide detailed exceptions (line numbers) on wrong content format.
It works with Java 8 but could fail in with next release. You've been warned.
Could be useful for prototyping though.
You can choose any readFully implementation from Convert InputStream to byte array in Java.
How can I post a file to a php using java (as a html form would do) ?
If you simply need to generate an HTTP Post, check out HttpClient, and in particular the PostMethod. Since you're talking HTTP the implementing technology on the server (in your case, PHP) is immaterial.
There's an example here.
It is in fact possible to do a POST using only the classes that are in the JDK, but as others have pointed out it will probably be easier to use a library like HttpClient.
In addition to HttpClient you may also want to look at the client-side java libraries supplied by RESTful frameworks such as Restlet and Jersey. While primarily designed for interacting with web services they offer a very high-level abstraction for GETing and POSTing to just about anything.
Code NOT tested or even compiled (probably doesn't compile), but this is kinda sorta would you'd do if you wanted to roll your own:
URL url = new URL("http://hostname/foo.php");
URLConnection connection = url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
// ignoring possible encoding issues
byte[] body = "param=value¶m2=value2".getBytes();
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded" );
connection.setRequestProperty("Content-length", String.valueOf(body.length) );
// ignoring possible IOExceptions
OutputStream out = connection.getOutputStream();
out.write(body);
out.flush();
// use this to read back from server
InputStream in = connection.getInputStream();
As you can see, it's pretty low-level stuff. Which is why you want to use a library.
The httpclient library contains all the tools you need to talk to a web server.