I have been going over the following tutorial and came across this code which I do not understand the purpose of:
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
I don't know what is the purpose of the above code and where is it writing this data to...
From what I could gather, the documentation states that it converts character to bytes... but then it writes it to some where... not sure why this is.
It is basically used for turning a character stream into a byte stream.
The byte streams and character streams are incompatible for linking as the first one operates on 8-bit ASCII characters and the other on 16-bit Unicode characters. To link them explicitly, two classes exist in java.io package, InputStreamReader and OutputStreamWriter.
InputStreamReader links a byte stream, with the character stream BufferedReader (on reading-side) .
Whereas with the OutputStreamWriter, the characters of 2-bytes are encoded (converted) into bytes of 1-byte (InputStreamReader does it other way – bytes to characters).
For a Java program to interact with a server-side process it simply must be able to write to a URL, thus providing data to the server. It can do this by following these steps:
1.Create a URL.
2.Retrieve the URLConnection object.
3.Set output capability on the URLConnection.
4.Open a connection to the resource.
5.Get an output stream from the connection.
6.Write to the output stream.
7.Close the output stream.
Now in the snippet you provided ,
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
creates an output stream on the connection and opens an
OutputStreamWriter on it--Step 5 If the URL does support output, then
this method returns an output stream that is connected to the input
stream of the URL on the server side — the client's output is the
server's input.If the URL does not support output, getOutputStream
method throws an UnknownServiceException.
And
wr.write( data );
wr.close();
wr.flush();
It writes the required information to the output stream and closes the
stream. The data written to the output stream on the client side is
the input on the server side.
It's writing it to the output stream of the URLConnection - which is basically used for the body of an HTTP request (assuming it's an HTTP URL, of course).
Related
I have to implement a post request in plain Java.
I have read the following question:
How to make a post request to a json RESTful Service from Java?
this is a part of the example
String url = "https://myStore.com/REST-API/";
String requestBody = "{\"searchProduct\": \"" + searchProduct + "\"}";
URL obj = new URL(url);
HttpsURLConnection connection = (HttpsURLConnection) obj
.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
OutputStream outputStream = connection.getOutputStream();
outputStream.write(requestBody.getBytes());
My question is: why the parameters are written on the output stream? As far as I know, output stream is for collecting the output of a request, not to make it.
So just a curiosity, consider that I am obviously not skilled on this.
First let explain how HttpConnectionURL works.
When you want to request data from a server,
you first create a connection to that server.
Then you write data to the connection (request)
and finally read data from the connection (response).
So to write data to the connection you get a reference to the Connection's OutputStream and write data to it.
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
writer.write("message=" + message);
To read data from the connection you get a reference to the Connection's InputStream and read data from it.
InputStreamReader reader = new InputStreamReader(connection.getInputStream());
reader.read();
Generally you use OutputStream when data is flowing out of your program (to file,network etc.,) and InputStream when data is flowing into your program (from file,network etc.,).
I think this will give you the clarity you are looking for.
This answer explains in detail how HttpConnectionURL works
The goal of InputStream and OutputStream is to abstract streams. By stream, I mean the way of the processed data (Input of the program or Output)
If the application receives information from the stream, use the InputStream. If it sends data then OutputStream
InputStreamused to read data from a source.
var input = new FileInputStream("input.txt");// Read the data
OutputStreamused for writing data to a destination.
var output = new FileOutputStream("output.txt");// Write the data
You should read answers in the related question : There are more explanations.
I'm having trouble using HttpUrlConnection. I'm working on multiple servers. Some servers send response in gzip encoding and some don't. For gzip encoding, I'm using
inputStream = new GZIPInputStream(connection.getInputStream());
inputStreamReader = new InputStreamReader(inputStream);
And for normal encoding, I'm using
inputStreamReader = new InputStreamReader(connection.getInputStream());
Is it possible to know the encoding of getInputStream so that I know beforehand whether or not to use GZIPInputStream. Or is there a generic input stream reader for both compressed & uncompressed. Thanks.
Get the content encoding from the HttpURLConnection using getContentEncoding().
It it's gzip-encoded, the result of that call should be gzip, and then you know what type of input stream you need to create.
I've got an issue with the URLConnection encoding trying to send a text.
My code is this:
final URL url = new URL(urlString);
final URLConnection urlConnection = url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
urlConnection.setRequestProperty("Accept-Charset", "UTF-8");
final DataOutputStream urlDataOut = new DataOutputStream(urlConnection.getOutputStream());
urlDataOut.writeBytes(prepareData.toString());
urlDataOut.flush();
urlDataOut.close();
My prepareData.toString() contains a word with an "è" and as soon as the urlDataOut is written it will contain the diamond with the question mark instead of the "è" letter and the status of the write is FAILURE.
Does anybody know how to face this issue?
The method DataOutputStream.writeBytes method is not suitable for any character encoding. Its documentation says:
Each character in the string is written out, in sequence, by discarding its high eight bits.
Using the method writeUTF will not be feasible either. It writes two bytes containing the length of the encoded String (number of bytes) which the server would interpret as characters at the beginning.
So you should use the standard way of writing text to an OutputStream:
Writer w=new OutputStreamWriter(
urlConnection.getOutputStream(), StandardCharsets.UTF_8);
w.write(prepareData.toString());
w.flush();
w.close();
I am trying to create a proxy server.
I want to read the websites byte by byte so that I can display images and all other stuff. I tried readLine but I can't display images. Do you have any suggestions how I can change my code and send all data with DataOutputStream object to browser ?
try{
Socket s = new Socket(InetAddress.getByName(req.hostname), 80);
String file = parcala(req.url);
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader dis = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter socketOut = new PrintWriter(s.getOutputStream());
socketOut.print("GET "+ req.url + "\n\n");
//socketOut.print("Host: "+req.hostname);
socketOut.flush();
String line;
while ((line = dis.readLine()) != null){
System.out.println(line);
}
}
catch (Exception e){}
}
Edited Part
This is what I should have to do. I can block banned web sites but can't allow other web sites in my program.
In the filter program, you will open a TCP socket at the specified port and wait for connections. If a
request comes (i.e. the client types a URL to access a web site), the application will process it to
decide whether access is allowed or not and then, using the same socket, it will send the reply back
to the client. After the client opened her connection to WebPolice (and her request has been checked
and is allowed), the real web page needs to be shown to the client. Therefore, since the user already gave her request, now it is WebPolice’s turn to forward the request so that the user can get the web page. Thus, WebPolice acts as a client and requests the web page. This means you need to open a connection to the web server (without closing the connection to the user), forward the request over this connection, get the reply and forward it back to the client. You will use threads to handle multiple connections (at the same time and/or at different times).
I don't know what exactly you're trying to do, but crafting an HTTP request and reading its response incorporates somewhat more than you have done here. Readline won't work on binary data anyway.
You can take a look at the URLConnection class (stolen here):
URL oracle = new URL("http://www.oracle.com/");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
Then you can read textual or binary data from the in object.
Read line will treat the line read as a String, so unless you want to mess around with conversions over to bytes, I wouldn't recommend that.
I would just read bytes until you can't read anymore, then write them out to a file, this should allow you to grab the images, keeping file headers intact which can be important when dealing with files other than text.
Hope this helps.
Instead of using BufferedReader you can try to use InputStream.
It has several methods for reading bytes.
http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html
This is my code
URL url = new URL("http://172.16.32.160:8080/epramaan/loginotp");
URLConnection connection1 = url.openConnection();
connection1.setDoOutput(true);
ObjectOutputStream out=new ObjectOutputStream(connection1.getOutputStream());
out.writeObject(send);
out.flush();
out.close();
ObjectInputStream in = new ObjectInputStream(connection1.getInputStream());
String output=(String)in.readObject();
in.close();
//Rest of the code
Once the OutputStream writes data to the stream, will the object InputStream stop execution till the response is received?
I assume that by stop execution you mean block.
Just noticed that you are using readObject and not read. Please elaborate what kind of data you are reading/writing and why are u using object streams ?
As you mentioned you are using String, I would suggest to use method readFully(byte[] buf). This method blocks till all the bytes are read. Once you have the byte array, a String can be created from this byte array.
You can use InputStream.read(byte[]) for reading the entire byte array to memory (you can get the array length from the HTTP Content-Length header) and use URLConnection.setReadTimeout() for timing out if you are blocking for too long.
From the byte array you can construct your object, constructing your ObjectInputStream over a ByteArrayInputStream
Once the OutputStream writes data to the stream, will the object InputStream stop execution till the response is received?
Not precisely. Opening the InputStream doesn't block anything, and doesn't even cause the request headers to be sent. However, reading from the InputStream will do both of those things.
I suspect that the real cause of your problems is that you are getting an error response from the server that is something other than a serialized object; e.g. it could be a generic HTML error page from the server. Naturally, attempting to deserialize this fails.
The correct procedure is:
Create the URLConnection object.
Set any request headers you need to.
Connect it (or skip this ... it will happen implicitly).
Open and write to the OutputStream.
Close the OutputStream.
Use getResponseCode() to see if the request succeeded or failed.
If it succeeded, call getInputStream() and read and process the response.
If it failed, call getErrorStream() and process the error output.