Receiving binary data over HTTP - java

I have a server which is sending a .png image to a client via a HTTP post request. The .png is stored inside a sqlite3 database, retrieved as a blob and this all works fine; I have tested saving the returned blob to disk and it can be opened as expected. When my client interprets the response, the payload has mysteriously grown in length from 16365 to 16367, inspecting the response string has shown there are some extra '?' characters intermittently in the stream
Testing the server using the ARC plug-in for Chrome has shown the response received there to be the right length, which leads me to believe there is a problem with my client code:
// request
URL url = new URL(targetURL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(parameters.getBytes().length));
conn.setRequestProperty("Content-Language", "en-US");
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.getOutputStream().write(parameters.getBytes());
// response
Reader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
for (int c; (c = rd.read()) >=0;)
sb.append((char)c);
String response = sb.toString();
// this String is of length 16367 when it should be 16365
Does anything jump out as being incorrect here? Note I am not doing any kind of character encoding on either side, should I be when using raw image data?

You can use DataInputStream to read the byte stream.
URL url = new URL("http://i.stack.imgur.com/ILTQq.png");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
DataInputStream dis = new DataInputStream(conn.getInputStream());
FileOutputStream fw = new FileOutputStream(new File("/tmp/img.png"));
byte buffer[] = new byte[1024];
int offset = 0;
int bytes;
while ((bytes = dis.read(buffer, offset, buffer.length)) > 0) {
fw.write(buffer, 0, bytes);
}
fw.close();
Alternatively an instance of BufferedImage can be created directly from the URL using ImageIO.read(java.net.URL).
URL url = new URL("http://i.stack.imgur.com/ILTQq.png");
BufferedImage image = ImageIO.read(url);

Related

Sending special characters using HttpURLConnection in Java

I have a web service and I want to invoke that with "application/x-www-form-urlencoded" content type. The request sometimes contains special characters such as + * - and .... The problem is that destination web service doesn't receive the request perfectly. It receives something like this: "////////////////w==" almost all characters are turned to / . What is the problem?
Here is my code:
URL url = new URL("a-web-service-url");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setUseCaches(false);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8");
outputStreamWriter.write("test=/-+*=!##$%^&*()_");
outputStreamWriter.flush();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder;
String line;
for (stringBuilder = new StringBuilder(); (line = bufferedReader.readLine()) != null; stringBuilder = stringBuilder.append(line)) {
;
}
bufferedReader.close();
httpURLConnection.disconnect();
String response = stringBuilder.toString().trim();
The web service receives:
test=////////////////w==
Use URLEncoder to encode the string before sending.
URLEncoder.encode(message, "UTF-8" );
In this case it will be
outputStreamWriter.write(URLEncoder.encode("test=/-+*=!##$%^&*()_", "UTF-8" ));

Why my Http request is done with `GET` instead of `POST`?

Why the code below do some GET request instead of POST resquest. I receive also CONTENT_TYPE: "" :(
HashMap<String, String> PostDataMap = new HashMap<>();
PostDataMap.put("method","any");
String PostDataString = HTTPEncodeParamNameValues(PostDataMap);
URL url = new URL(ApiServerURL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setUseCaches(false);
DataOutputStream dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream());
dataOutputStream.writeBytes(PostDataString);
dataOutputStream.flush();
dataOutputStream.close();
InputStream inputStream = url.openConnection().getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, length);
}
when you pass some user input to server that time used post and only getting data no user input that time used get.
when used get that time all data call in url. and it limited size. and also not secure.
when you used post that not go data into url. and is unlimited data to be send .and also secure.

Download File with Http Request and UTF-8

I wrote a code like this.
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Cache-Control", "no-cache");
int responseCode = con.getResponseCode();
InputStream inputStream = con.getInputStream();
FileOutputStream outputStream = new FileOutputStream("C:\\aaaa\\ww.csv");
int bytesRead = -1;
byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
The code works well.I send request and ı can download the csv file into my computer.But ı want to know that if the csv file have turkish characters(ş,ğ,ı,ç) can ı download the csv with that characters.
or what can ı do for that characters to see them in csv file.
The server sends you a stream of bytes and you just save the byte stream on your disk, so you don't need to worry about characters.

Send file from Action to Servlet

My goal is to upload a file from an action to a servlet.
Till now, I thought I had it working in this way:
Action: reads file as bytearray, converts it into String and puts String on request
HttpURLConnection conn =null;
String url = "http://myServlet");
URL obj = new URL(url);
conn = (HttpURLConnection) obj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
StringBuffer requestParams = new StringBuffer();
requestParams.append("fileString");
requestParams.append("=").append(URLEncoder.encode(fileString, "ISO-8859-1"));
//Append more params
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(requestParams.toString());
wr.flush();
conn.getContentLength();
Servlet: get String parameter, converts it back to bytearray and re-creates the file
receivedString = request.getParameter("fileString");
//Convert to bytearray and create file
But I guess this isn't a good solution, cause sometimes the call just fails because of the string (length maybe?)
Which is the right way to send my file? I can't find a way to send the file AND additional informations putting them on the request.

Read Status code

conn = (HttpURLConnection) connectURL.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.connect();
int code = conn.getResponseCode();
I have successfully established a connection. I am trying to pass the information over the internet.When the url is opened via browser I am getting response as
{"status":"0","responseCode":"1001","response":"Wrong Settings."}
For correct status is returned as 1.
Is there any method where I can get the status only.I have been trying the following methods but every time I am getting code (below is code snippet) as -1 irrespect of status code when I am verifying manually via browser
This is a JSON text. You will need to use a JSON library.
int code = conn.getResponseCode();
this method returns http status code, for http status codes see
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
while the response code you want to retrieve is actually the response string returned by the server.
To read this use:
try {
InputStream in = new BufferedInputStream(conn.getInputStream());
readStream(in);//method to read characters from stream.
finally {
urlConnection.disconnect();
}
}
You can add below code for get Response string from your connection.
OutputStream connectionOutput = null;
connectionOutput=connection.getOutputStream();
connectionOutput.write(requestJson.toString().getBytes());
connectionOutput.flush();
connectionOutput.close();
inputStream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream dataCache = new ByteArrayOutputStream();
// Fully read data
byte[] buff = new byte[1024];
int len;
while ((len = inputStream.read(buff)) >= 0) {
dataCache.write(buff, 0, len);
}
// Close streams
dataCache.close();
Now get Response string of json like below.
String jsonString = new String(dataCache.toByteArray()).trim();
JSONObject mJsonobject=new JSONObject(jsonString);
You can now parse your key from this mJsonobject Object.

Categories