Getting java.io.IOException: Error writing to server at getInputStream - java

If the temp string is very large I get java.io.IOException: Error writing to server at getInputStream
String tmp = js.deepSerialize(taskEx);
URL url = new URL("http://"
+ "localhost"
+ ":"
+ "8080"
+ "/Myproject/TestServletUpdated?command=startTask&taskeId=" +taskId + "'&jsonInput={\"result\":"
+ URLEncoder.encode(tmp) + "}");
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
Why is that?
This call goes to the servlet mentioned in the URL.

Use HTTP POST method instead of putting all the data in the URL for GET method. There is an upper limit for the length of the URL, so you need to use POST method if you want to send arbitrary length data.
You may want to modify the URL to http://localhost:8080/Myproject/TestServletUpdated, and put the rest
command = "startTask&taskeId=" + taskId + "'&jsonInput={\"result\":" + URLEncoder.encode(tmp) + "}"
in the body of the POST request.

I think you might have a "too long url", the maximum number of characters are 2000 (see this SO post for more info). GET requests are not made to handle such long data input.
You can, if you can change the servlet code also, change it into a POST instead of a GET request (as you have today). The client code would look pretty simular:
public static void main(String[] args) throws IOException {
URL url = new URL("http", "localhost:8080", "/Myproject/TestServletUpdated");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write("command=startTask" +
"&taskeId=" +taskId +
"&jsonInput={\"result\":" + URLEncoder.encode(tmp) + "}");
wr.flush();
.... handle the answer ...
}
I didn't see it first but it seems like you have a single quote character in your request string.
...sk&taskeId=" + taskId + "'&jso.....
^
try removing it, it might help you!

getInputStream() is used to read data. Use getOutputStream()

It could be because the request is being sent as a GET which has a limitation of a very few characters. When the limit exceeds you get an IOException. Convert that to POST and it should work.
For POST
URLConnection conn = url.openConnection().
OutputStream writer = conn.getOutputSteam();
writer.write("yourString".toBytes());
Remove the temp string from the url that you are passing. Move the "command" string to the "yourString".toBytes() section in the code above

Related

Looking for an alternate way to validate URLs in Java

I'm using HttpURLConnection to validate URLs coming out of a database. Sometimes with certain URLs I will get an exception, I assume they are timing out but are in fact reachable (no 400 range error).
Increasing the timeout doesn't seem to matter, I still get an exception. Is there a second check I could do in the catch region to verify if in fact the URL is bad? The relevant code is below. It works with 99.9% of URLs, it's that .01%.
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.13) Gecko/2009073021 Firefox/3.0.13");
connection.connect () ;
int responseCode = connection.getResponseCode();
if (responseCode >= 401)
{
String prcMessage = "ERROR: URL " + url + " not found, response code was " + responseCode + "\r";
System.out.println(prcMessage);
VerifyUrl.writeToFile(prcMessage);
return (false);
}
}
catch (IOException exception)
{
String errorMessage = ("ERROR: URL " + url + " did not load in the given time of " + timeout + " milliseconds.");
System.out.println(errorMessage);
VerifyUrl.writeToFile(errorMessage);
return false;
}
Depends on what you want to check. But i guess Validating URL in Java got you covered.
You got two possiblities:
Check syntax ("Is this URL a real URL or just made up?")
There is a large amount of text which describes how to do it. Basically search for RFC 3986. I guess someone has implemented a check like this already.
Check the semantics ("Is the URL available?")
There is not really a faster way to do that though there are different tools available for sending a http request in java. You may send a HEAD request instead of GET as HEAD omits the HTTP body and may result in faster requests and less timeouts.

Http POST in android app without data

I'm trying to send a video url in a http POST request but it's not working for me, I think I've (almost?) the necessary code to make it work, or else I'm missing something very simple?
public void postVideoURL() throws IOException {
String encodedUrl = URLEncoder.encode("http://video.ted.com/talks/podcast/DavidBrooks_2011.mp4", "UTF-8");
URL obj = new URL("http://10.50.0.105:8060/launch/dev?url="+encodedUrl);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
// Send post request
con.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
System.out.println(con.getResponseCode());
System.out.println(con.getResponseMessage());
wr.flush();
wr.close();
wr.write("");
}
Any tips to lead me to the right direction?
Here is what I'm trying to do but in C#
using System.Net;
using System.Web;
class Program
{
static void Main()
{
string rokuIp = "192.168.0.6";
string channelId = "dev";
string videoUrl = "http://video.ted.com/talks/podcast/DavidBrooks_2011.mp4";
// Note that the query string parameters should be url-encoded
string requestUrl = $"http://{rokuIp}:8060/launch/{channelId}?url={HttpUtility.UrlEncode(videoUrl)}";
using (var wc = new WebClient())
{
// POST the query string with no data
wc.UploadString(requestUrl, "");
}
}
}
The following Post command to use in terminal works, this is essentially what I want to do, but in Java:
curl -d "" "http://10.50.0.46:8060/launch/12?url=http%3A%2F%2Fvideo.ted.com%2Ftalks%2Fpodcast%2FDavidBrooks_2011.mp4"
You are never writing anything to the output stream. You have to call wr.write() to write your data to the stream.
Also, you can't encode the URL like that inside the String. You need to concatenate the two Strings together after you've encoded the url separately. Like this:
String encodedUrl = URLEncoder.encode("http://video.ted.com/talks/podcast/DavidBrooks_2011.mp4");
URL obj = new URL("http://10.50.0.105:8060/launch/dev?url="+encodedUrl);

How to send a GET request with a "/" in the query

I'm trying to write a test program to test my web service. I'm sending a JSON object to my web service via the GET method but it's not working. My test URL looks like this:
http://testserver:8080/mydir/{"filename":"test.jpg", "Path":"test/2/2"}
I'm thinking the "/" in the path are causing me problems since the program works fine once I remove them.
Per REST how to pass values containing "/" as path parameter in the URI?, I've tried to use java.net.URLEncoder.encode but that isn't helping. Here's a snippet of my test program:
// some code from main method
<snip snip>
String url = "http://testserver:8080/mydir/";
String JSON = "{\"filename\":\"test.jpg\",\"Path\":\"test/2/2\"}";
String enc_JSON = URLEncoder.encode(JSON,"UTF-8");
String testGet = url + enc_JSON;
String out2 = TestCode.httpGet(testGet);
<snip snip>
// code from httpGet method
public static String httpGet(String serverURL) {
URL url;
HttpURLConnection conn;
try {
url = new URL (serverURL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
// failing at line below
InputStream input = conn.getInputStream();
<snip snip>
The result of my program is I get an HTTP response code: 400. Did I forget to add something in my code in the httpGet() method that's causing it to fail or am I doing something illegal in my URL due to the JSON object being tacked on at the end with the "/" in the path location?
Thanks in advance for you help.
For REST APIs, JSON objects are typically sent (POST) or returned in the body of the request. They are not typically encoded as part of the URL.
For a GET request, you can either pass the information as segments in the url or as querystring parameters.
As segments in the url:
/resourcetype/{path}/{filename}
http://testserver:8080/resourcetype/test/2/2/test.jpg
As querystring params:
/resourcetype?path={path}&file={filename}
http://testserver:8080/resourcetype?path=test/2/2&filename=test.jpg

how to make a fql query in java

Hy,
I want to make a fql query on stream table.The code is:
URL url = new URL("https://graph.facebook.com/fql?q=SELECT source_id"+
",created_time,permalink FROM stream WHERE and"+
" source_id=.. limit 1000 & access_token=...");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStream responseStream = connection.getInputStream();
System.out.println(connection.getHeaderFields());
System.out.println("=== Content ===");
while (((c = responseStream.read()) != -1)) {
System.out.print((char) c);
In browser if i type this url it works but in my code doesnt work only if i but some characters like: %20%20 ...is there any way to write the url in my code without this?
You must perform URL encoding: URLEncoder.encode(url). This is required by HTTP spec. The URL will be decoded automatically at server side, so the application will get it in "pure" form.

Sending Java POST request without calling getInputStream()

I would like to send a POST request in Java. At the moment, I do it like this:
URL url = new URL("myurl");
URLConnection con = url.openConnection();
con.setDoOutput(true);
PrintStream ps = new PrintStream(con.getOutputStream());
ps.println("key=" + URLEncoder.encode("value"));
// we have to get the input stream in order to actually send the request
con.getInputStream();
ps.close();
I do not understand why I have to call con.getInputStream() in order to actually send the request. If I do not call it, the request is not sent.
Is there a problem using PrintStream? It should not matter if I take a PrintStream, PrintWriter or something else, right?
URL represents some source.
URLConnection represents a connection to the resource.
you need call connection.connect() to connect the connection
Try to add con.setDoInput (false); before writing to the output.
P.S.: and you should also call con.connect () as swanliu says.
Update
This is what I came up with
private static final void sendPostRequest (final String urlAddress, String key, String value) throws Exception
{
URL url = new URL (urlAddress);
URLConnection con = url.openConnection ();
con.setDoOutput (true);
con.setDoInput (false);
PrintStream ps = new PrintStream (con.getOutputStream ());
ps.println (key + "=" + URLEncoder.encode (value, "UTF-8"));
ps.flush ();
con.connect ();
ps.close ();
}
I checked with WireShark that a tcp connection is being established and that closed. But don't know how check that the server received the request.
If you have a quick way to check it you may try that code.
I think a post of another thread answered my question. Sorry, but I found it too late. You can find it here.
PS: Unfortunately, Stackoverflow added my last answer to the question as a comment, because my answer was too short. And it is not possible to mark a comment as the correct answer... Hope this one is long enough :-)
I think this is the easiest way.
con.setDoOutput(true);
PrintStream ps = new PrintStream(con.getOutputStream());
ps.print("&client_id="+ 2);
ps.print("&amount="+10);
ps.flush();
ps.close();

Categories