I'm trying to use HttpURLClient to send some POST data to a server using the HttpRestClient class shown below. When executing
conn.setDoInput(true);
I get
java.lang.IllegalStateException: Already connected
I uninstalled the app, and still get the same error.
In all the example I've seen openConnection is called before setDoInput. If, as its name suggests, openConnection opens a connection, it should never be used before `setDoInput, right? What am I missing?
Maybe at some point it crashed before executing disconnect. Could that be the reason? If so, how can I disconnect the old connection?
public class HttpRestClient {
static public int post(String urlStr, List<NameValuePair> data){
HttpURLConnection conn = null;
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getQuery(data));
writer.flush();
writer.close();
os.close();
InputStream is = conn.getInputStream();
String dude = readIt(is);
return 1;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return 0;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return 0;
}
finally {
if(conn!=null) conn.disconnect();
}
}
}
This might be due to watches while debugging in your IDE. See this answer.
It happened to me and was hard to discover.
You called both of conn.setDoInput(true); and conn.setDoOutput(true);. Use one of them:
setDoOutput(true) is used for POST and PUT requests.
setDoInput(true) is used for GET request.
The connection you made was confused, it can't decide which request should be used.
In your code:
static public int post(String urlStr, List<NameValuePair> data){
HttpURLConnection conn = null;
System.setProperty("http.keepAlive", "false"); // must be set
try {
...
conn.setDoOutput(true);
conn.setRequestMethod("POST");
// and connect to server, if needed
conn.connect();
...
}
....
It may be a misleading exception. See this defect for Jersey-2 https://java.net/jira/browse/JERSEY-2729
The link has been updated:
https://github.com/javaee/jersey/issues/3001
Basically the issue is jersey was throwing invalid exception. The real issue in my case was that the connection was refused from the server.
Related
I want to get XML data from the web server https://ruralfire.qld.gov.au/bushfirealert/bushfireAlert.xml
However, I can't do it because my codes always have an error "javax.net.ssl.SSLHandshakeException: Connection closed by peer".
And my InputStream is always null, so I can't do anything with it (such as parsing).
I ensure that the problem is in my connection but I don't know how to solve it.
This is my code in connecting to the web server:
private InputStream downloadUrl(String urlString) throws IOException {
URL url;
url = new URL(urlString);
InputStream is = null;
try {
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setDoInput(true);
is = con.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
May you help me to solve this problem ?
Thank you so much.
I'm trying to create an android application which depends on JSON responses. Sometimes it takes a lot of time for the server to respond and ends in a time out exception. Therefore I would like to add a restriction like my webservice call should abort after 20seconds if there is no response. Can you please help me achieving this idea.
Thanks in Advance.
You're not giving much details on the actual implementation that you have.
However, messing with the timeout seems like it may be an emergency fix to an underlying problem that should be fixed.
However, using websockets for transport could be a possible (and probably more elegant) solution. They provide a persistent connection between client and server once created.
Using websockets on Android and IOS
There are several ways to achieve the goal.
We can using HttpURLConnection to do the http request.
public String doPost() {
if (!mIsNetworkAvailable) {
return null;
}
try {
URL url = new URL(mURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
for (String key : mHeadersMap.keySet()) {
conn.setRequestProperty(key, mHeadersMap.get(key));
}
conn.setRequestProperty("User-Agent", "Android");
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setRequestProperty("Content-Type", "application/json");
conn.getOutputStream().write(mContent);
conn.getOutputStream().flush();
int rspCode = conn.getResponseCode();
if (rspCode >= 400) {
return null;
}
byte[] buffer = new byte[8 * 1024];
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
while ((len = bis.read(buffer)) > 0) {
baos.write(buffer, 0, len);
}
baos.flush();
final String result = new String(baos.toByteArray());
baos.close();
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
setConnectTimeout :Sets the maximum time in milliseconds to wait while connecting.
setReadTimeout:Sets the maximum time to wait for an input stream read to complete before giving up.
Reference: http://developer.android.com/reference/java/net/URLConnection.html
I am trying to post a JSON message to a site and to retrieve a JSON message back.
java.net.ProtocolException: method does not support a request body: POST
Does anyone know what is wrong? Thanks in advance
HttpURLConnection conn=null;
try{
URL url=new URL(urlString);
String userPassword = userName +":" + passWord;
byte[] bytes=Base64.encode(userPassword.getBytes(),Base64.DEFAULT);
String stringEncoding = new String(bytes, "UTF-8");
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty ("Authorization", "Basic " + stringEncoding);
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
Log.i("Net", "length="+conn.getContentLength());
Log.i("Net", "contentType="+conn.getContentType());
Log.i("Net", "content="+conn.getContent());
conn.connect();
}catch(Exception e){
Log.d("Url Formation Connection", e.toString());
}
//output{
try{
String requestString="{“ ";
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(requestString.toString());
wr.flush();
//input{
BufferedReader rd = null;
String response=" ";
is = conn.getInputStream();
rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer responseBuff = new StringBuffer();
while ((line = rd.readLine()) != null) {
// Process line...
responseBuff.append(line);
}
response = responseBuff.toString();
Log.d("response", response);
}catch(Exception e){
Log.d("buffer error", e.toString());
}finally {
if (is != null) {
try {
wr.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It could be that the server you're connecting to doesn't allow POST operations. I would try a GET request first, to see if you have permissions for that web service method.
Also, you could try your luck with a simpler HttpClient, although I haven't tested this solution myself: http://www.geekmind.net/2009/11/android-simple-httpclient-to.html
Just a guess but can you try setting:
conn.setDoOutput(false);
The documentation says: "Optionally upload a request body. Instances must be configured with setDoOutput(true) if they include a request body." HttpURLConnection
Since you do not have anything in your body, might as well set it to false.
The documentation Android has for setRequestMethod is minimal, however your error states that POST is not a valid method. Try using PUT instead:
conn.setRequestMethod("PUT");
Also see this post for any tweaks you may need to make.
I want to access a url in my android activity, for storing a string thats passed as a parameter on the url itself with a webservice that i have built. at this point, i just want to access the url and see that it happens, and later on i will worry about doing something with the result (what the request returns back). I'm using HttpURLConnection. I'm getting this error:
D/SntpClient( 59): request time failed: java.net.SocketException: Address fami
ly not supported by protocol
my code is:
public void storeScore()
{
Log.d("storeScore","is running");
HttpURLConnection con = null;
//DefaultHttpClient
try {
URL url = new URL("http://www.google.com");
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(10000);
con.setConnectTimeout(15000);
con.setRequestMethod("GET");
con.setDoInput(true); //also tried without this
con.setDoOutput(true); //also tried without this
con.connect();
Log.d("storeScore","got to connect");
//not really reading the result at this point:
//BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
//String payload = reader.readLine();
//reader.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("MalformedURLException",e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("IOException",e.getMessage());
e.printStackTrace();
}
}
the app android manifest includes both premissions:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
this method storeScore() is ran from a thread that is created onCreate and started. Am i doing something wrong here? If you need more relevant information that i didn't add here, tell me and I will edit the question. Thanks, i appreciate any assistance.
I am trying for post data(username and password in JSON format for login) from android application to php server - drupal cms website using HttpUrlConnection .
Here is my code , For login.
I am getting this response:
java.net.ProtocolException: OutputStream unavailable because request
headers have already been sent!
I have searched on google & other stackoverflow questions but cant find any solution to my problem. So Please Help.
Thanks for listening.
HttpURLConnection httpcon = null;
int status = 0;
try {
httpcon = (HttpURLConnection) ((new URL("my URL here").openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
status = httpcon.getResponseCode();
httpcon.getHeaderFields();
System.out.println("===================>httpcon.getHeaderFields()"+httpcon.getHeaderFields());
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
httpcon.connect();
byte[] outputBytes = "{'username':'uname','password':'pass'}".getBytes("UTF-8");
OutputStream os = httpcon.getOutputStream();
os.write(outputBytes);
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return status;
You call httpcon.getResponseCode() and httpcon.getHeaderFields() in the first part of your code. As mentioned in the javadoc for HttpUrlConnection, this causes the HTTP request to be executed. This makes sense, because to read the response header fields you need a response, and to get a response you have to issue the request.
You then do the output stream stuff, which fails because the request has already been sent.
To make this work, you need to re-order your code so that all the request stuff is set up before you access the response stuff. Something along these lines:
byte[] outputBytes = "{'username':'uname','password':'pass'}".getBytes("UTF-8");
try {
HttpURLConnection httpcon = (HttpURLConnection) ((new URL("my URL here").openConnection()));
//prepare the request
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
httpcon.connect(); // May not be needed
OutputStream os = httpcon.getOutputStream();
os.write(outputBytes);
//get the response
status = httpcon.getResponseCode();
httpcon.getHeaderFields();
System.out.println("===================>httpcon.getHeaderFields()"+httpcon.getHeaderFields());
} //catch block left out