HTTPUrl connection closed automatically - java

i am reading a xml response using httpurlconnection. i parsed the response using JAXB. I didnt close the connection. When i again try to read from the URL , I am getting the error as Input stream. Do i have to open connection twice or is there any way to open connection once and read the response twice and then close the connection?

JAXB likely consumes the InputStream and then closes it. You would need to use some kind of FilterInputStream so that it's buffered and reusable.
With Guava, you can do something like
HttpURLConnection con = ...; // get it
InputStream in = con.getInputStream();
String content = CharStreams.toString(new InputStreamReader(in, Charsets.UTF_8));
Then pass a new InputStream to JAXB made from the bytes of content.
InputStream inForJAXB = new ByteArrayInputStream(content.getBytes());
You can do the same thing again for any other component that needs the content of the HttpURLConnection input stream.

Related

What is the role of getInputStream() here?

I have a JSON object which I'm trying to write to the json file. I think the write() method of the OutputStreamWriter object is responsible for writing to the json file but if I don't add the last line "urlConnection.getInputStream();" the changes do not take effect. Please explain what this line is doing and why do I need it because as far as I know getInputStream() is used to read an input stream from the open connection not write to the open connection.
URL database_url = new URL("https://example.firebaseio.com/posts.json");
URLConnection urlConnection = database_url.openConnection();
urlConnection.setRequestProperty("X-Requested-With", "Curl");
urlConnection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
out.write(obj.toJSONString());
out.close();
urlConnection.getInputStream();

Parsing XML response of SOAP call in Weblogic

We are in the process of migrating functionality from a Weblogic Server 8,1 sp5 with java 1.4 to 10.3.6 with java 1.7.
The case that is described below is working properly in the old server, however we are facing an issue when transferring the handling to the new one.
The problem lies while retrieving and parsing an XML response that was retrieved from an external system through SOAP calls.
The following libraries and procedure are used in the method:
java.net.HttpURLConnection to make the connection
java.io.OutputStream to send the request
java.io.InputStream to get the response
byte[] to store the result before transforming in to String
javax.xml.parsers.DocumentBuilder, java.io.StringReader and org.xml.sax.InputSource to transform the String into org.w3c.dom.Document
The following exception is thrown:
"org.xml.sax.SAXParseException - Content is not allowed in trailing section."
When opening the logs of the application with notepad++ many null characters appear after the end of the file which seem to cause the issue. I repeat that no such cases appear when executing the request from the old server.
The respective code is the following:
//Creating the connection
URL u = new URL(default_server);
URLConnection uc = u.openConnection();
HttpURLConnection connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod(requestMethod);
connection.setRequestProperty("SOAPAction", soap_action);
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
wout.write(xmlString);
wout.flush();
wout.close();
InputStream in = connection.getInputStream();
int c = in.available();
byte r[] = new byte[c];
in.read(r);
String response = new String(r);
connection.disconnect();
//Transorming the String to XML Doc
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader theReader = new StringReader(response);
InputSource theInputSource = new InputSource();
theInputSource.setCharacterStream(theReader);
Document doc = builder.parse(theInputSource);
//Here occurs org.xml.sax.SAXParseException-Content is not allowed in trailing section
return doc;
I know that i can solve the issue by getting the stripping the response from junk characters but this not a safe resolution.
Do you have any information to share on the matter? Do you think it is a java version issue or maybe a server configuration issue?
Thank you in advance your time.
Best Regards,
George
I see two issues
in.available() as per the javadoc: Returns an estimate of the number of bytes... Do not rely on this. Loop over buffers of 8K to read the stream until you reach the end or even better, do not re-invent the wheel, use commons-io from Apache and use a single call to ÌOUtils.read
String response = new String(r); doing this you are assuming that the bytes received are encoded using the same charset as your platform encoding/charset. It is unlikely to be the case if you are on Windows or OSX. You must pass the charset and use the constructor String(byte[] bytes, Charset charset).

Java - Unable to write on URLConnection

I need to add contents on file existing in tomcat server. So, I am using URLConnection to do this task.
Code I am trying:
URL url = new URL("http://localhost:8080/css/extractedcss.css");
URLConnection urlcon = url.openConnection();
urlcon.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(
urlcon.getOutputStream());
out.write("New Text");
out.close();
No any exception I am getting during execution of above code but when I look into the file, no any new text I am getting.
Please help!
Regards,
You can't write directly to a file in your tomcat server - at least, not in HTTP you can't.
You'll have to write a servlet to do the writing for you, and then use a POST/PUT request to this servlet with the data you want written.

Sending Binary and Textdata via HTTP POST

I try to use HTTP POST to send some Data to a Server.
The Server expects the binary Data in $_POST['file'].
URL url = new URL("http://example.com");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
OutputStream outputStream = connection.getOutputStream();
outputStream.write("file=".getBytes());
//byte[] buffer contains the data
outputStream.write(buffer);
outputStream.close();
Is OutputStream.write the right method to write into the stream? Do I have to handle the string ("file=") other then the buffer?
I recommend converting your data to Base64 String (Compatibility with all systems).
string result = Convert.ToBase64String(Encoding.UTF8.GetBytes(utf8Text));
Yes, to write text with POST, you will need to write to `OutputStream.
For parameters, you will need to create a String of key-value pair (separated with &) and write the byte array of that data in OutputStream as follows:
String parameterString = "file=" + parameters.get("file") + "&" + "other=" + parameter.get("other");
outputStream.write(parameterString.getBytes("UTF-8"); //Don't forget, HTTP protocol supports UTF-8 encoding.
outputStream.flush();
To do file upload with URLConnection, see BalusC's article How to use java.net.URLConnection to fire and handle HTTP requests?

Does new URL(...).openConnection() necessarily imply a POST?

If I create an HTTP java.net.URL and then call openConnection() on it, does it necessarily imply that an HTTP post is going to happen? I know that openStream() implies a GET. If so, how do you perform one of the other HTTP verbs without having to work with the raw socket layer?
If you retrieve the URLConnection object using openConnection() it doesn't actually start communicating with the server. That doesn't happen until you get the stream from the URLConnection(). When you first get the connection you can add/change headers and other connection properties before actually opening it.
URLConnection's life cycle is a bit odd. It doesn't send the headers to the server until you've gotten one of the streams. If you just get the input stream then I believe it does a GET, sends the headers, then lets you read the output. If you get the output stream then I believe it sends it as a POST, as it assumes you'll be writing data to it (You may need to call setDoOutput(true) for the output stream to work). As soon as you get the input stream the output stream is closed and it waits for the response from the server.
For example, this should do a POST:
URL myURL = new URL("http://example.com/my/path");
URLConnection conn = myURL.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStream os = conn.getOutputStream();
os.write("Hi there!");
os.close();
InputStream is = conn.getInputStream();
// read stuff here
While this would do a GET:
URL myURL = new URL("http://example.com/my/path");
URLConnection conn = myURL.openConnection();
conn.setDoOutput(false);
conn.setDoInput(true);
InputStream is = conn.getInputStream();
// read stuff here
URLConnection will also do other weird things. If the server specifies a content length then URLConnection will keep the underlying input stream open until it receives that much data, even if you explicitly close it. This caused a lot of problems for us as it made shutting our client down cleanly a bit hard, as the URLConnection would keep the network connection open. This probably probably exists even if you just use getStream() though.
No it does not. But if the protocol of the URL is HTTP, you'll get a HttpURLConnection as a return object. This class has a setRequestMethod method to specify which HTTP method you want to use.
If you want to do more sophisticated stuff you're probably better off using a library like Jakarta HttpClient.

Categories