HttpURLConnection GET request on Android gives weird 501 code - java

I have a weird issue when using HttpURLConnection on android it gives me a status code 501 but when I try the request on curl, it gives me status code 200.
curl -X GET \
-H "Accept-Charset: UTF-8" \
https://domain.com/v1/resource?token=token12345
This is my HttpURLConnection GET request snippet
public MyResponse get(String params) {
HttpURLConnection connection = null;
InputStreamReader inputStream = null;
BufferedReader reader = null;
MyResponse response = null;
String tokenParam = "?token=" + params;
try {
URL url = new URL(BASE_URL + API_VER + mResource + tokenParam);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(Method.GET);
connection.setRequestProperty(Header.ACCEPT_CHARSET, Value.UTF_8);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
int statusCode = connection.getResponseCode(); // code 501
inputStream = new InputStreamReader(connection.getInputStream());
reader = new BufferedReader(inputStream);
StringBuilder message = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
message.append(line);
}
response = new MyResponse();
response.setMessageBody(message.toString());
response.setStatusCode(statusCode);
if (statusCode == HTTP_OK || statusCode == HTTP_CREATED) {
response.setSuccess(true);
} else {
response.setSuccess(false);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) connection.disconnect();
try {
if (inputStream != null) inputStream.close();
if (reader != null) reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return response;
}
Am I missing anything?

setDoOutput(true) is used for POST and PUT requests for sending (output) a request body. Usually we don't need this for GET requests. Found it here

Ignore the timeout stuff if you don't need it.
The method at the bottom just takes an input stream and converts it into a response for you.
Hope it helps.
public boolean genLogon(){
HttpGet m_httpGet = null;
HttpResponse m_httpResponse = null;
// setup timeout params for the socket and the time to connect
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = CONNECTION_TIMEOUT;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = DATA_TIMEOUT;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
// Create a http client with the parameters
HttpClient m_httpClient = new DefaultHttpClient(httpParameters);
String result = null;
try {
// Create a get object
m_httpGet = new HttpGet("https://domain.com/v1/resource?token=token12345");
m_httpGet.setHeader(Accept-Charset, "UTF-8");
m_httpResponse = m_httpClient.execute(m_httpGet);
HttpEntity entity = m_httpResponse.getEntity();
if (entity != null) {
// Get the input stream and read it out into response
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
// now you have the string representation of the HTML request
instream.close();
}
} catch (ConnectTimeoutException cte) {
// Toast.makeText(MainApplication.m_context, "Connection Timeout", Toast.LENGTH_SHORT).show();
return false;
} catch (Exception e) {
return false;
} finally {
m_httpClient.getConnectionManager().closeExpiredConnections();
}
// See if we have a response
if (m_httpResponse == null) {
return false;
}
// check status
if (m_httpResponse.getStatusLine() == null) {
return false;
}
// If the status code is okay (200)
if (m_httpResponse.getStatusLine().getStatusCode() == 200) {
//Handle the repsonse
return true
} else {
// response code not 200
}
return false;
}
private static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine() method. We iterate until the
* BufferedReader return null which means there's no more data to read. Each line will appended to a
* StringBuilder and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}

Related

how can i obtain the response off server and if this contains "open" i can call other method, "contains" always marks error

/Method that sends the GPS pulse every time, when receiving the answer of the server if it contains "open" I have to stop sending pulse The method of eliminating the pulse I already have, I just have to know if the server response contains "open" because the response from the Server is too large string coming from a JSON/
#Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader bufferedReader = null;
final String routeId = ControlClass.pref.getString("routeId", "inaccesible");
int routeId2= Integer.parseInt(routeId);
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
JSONObject jsonParam = new JSONObject();
jsonParam.put("route_id", routeId2);
jsonParam.put("timestamp", timestamp);
jsonParam.put("lat", 19.5216103);
jsonParam.put("lon", -99.21071050509521);
Log.d("BANDERA", "LIVE TRACKING");
Log.d("JSON DEL LIVE TRACKING", jsonParam.toString());
System.out.println("Latitud y longitud" + currentLatitude + currentLongitude);
wr.writeBytes(jsonParam.toString());
wr.flush();
wr.close();
urlConnection.connect();
try {
InputStream is = urlConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(is));
String line;
StringBuilder response = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
response.append(line);
response.append('\r');
}
bufferedReader.close();
if(serverAnswer.contains("open"))
killGps();
serverAnswer = response.toString();
System.out.println("LIVE TRACKING RESPONSE" + serverAnswer);
Log.d("LIVE TRACKING RESPONSE", serverAnswer);
return response.toString();
} catch (FileNotFoundException e) {
Log.d("ERROR: ", "File not found en servidor Response: " + serverAnswer);
}
} catch(Exception e){
e.printStackTrace();
return null;
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return serverAnswer;
}
}
If you don't need the entire response, don't store it. Just search each line as you stream it, and exit once you find the text you're looking for:
while ((line = bufferedReader.readLine()) != null) {
if (line.contains("open")) {
killGps();
break;
}
}

Android HttpURLConnection wierd response

I am trying to get response data of a Http request. My code looks like this :
public class Networking {
// private variables
private URL mUrl;
private InputStream mInputStream;
public void Networking() {}
public InputStream setupConnection(String urlString) {
// public variables
int connectionTimeout = 10000; // milliseconds
int readTimeout = 15000; // milliseconds
try {
mUrl = new URL(urlString);
try {
// initialize connection
HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
// setup connection
connection.setConnectTimeout(connectionTimeout);
connection.setReadTimeout(readTimeout);
connection.setRequestMethod("GET");
connection.setDoInput(true);
// start the query
try {
connection.connect();
int response = connection.getResponseCode();
if (response == 200) {
// OK
mInputStream = connection.getInputStream();
return mInputStream;
} else if (response == 401) {
// Unauthorized
Log.e("Networking.setupConn...", "unauthorized HttpURL connection");
} else {
// no response code
Log.e("Networking.setupConn...", "could not discern response code");
}
} catch (java.io.IOException e) {
Log.e("Networking.setupConn...", "error connecting");
}
} catch (java.io.IOException e) {
Log.e("Networking.setupConn...", "unable to open HTTP Connection");
}
} catch (java.net.MalformedURLException e) {
Log.e("Networking.setupConn..", "malformed url " + urlString);
}
// if could not get InputStream
return null;
}
public String getStringFromInputStream() {
BufferedReader br = null;
StringBuilder sb = new StringBuilder(5000);
String line;
try {
br = new BufferedReader(new InputStreamReader(mInputStream), 512);
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (java.io.IOException e) {
Log.e("BufferReader(new ..)", e.toString());
return null;
} finally {
if(br != null) {
try {
br.close();
}catch (java.io.IOException e) {
Log.e("br.close", e.toString());
}
}
}
return sb.toString();
}
}
The problem is that the getStringFromInputStream function always returns a string that is 4063 bytes long. ALWAYS! No matter what the url.
I checked, and the (line = br.readLine()) part of the code always returns a string of fixed length of 4063.
I don't understand this. Please help.
This my code which works for me:
public String getDataFromUrl(String httpUrlString)
URL url = new URL(httpUrlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
responseCode = urlConnection.getResponseCode();
if (responseCode != HttpStatus.SC_OK) {
return null;
} else { // success
BufferedReader in = null;
StringBuffer str = new StringBuffer();
try {
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
str.append(inputLine);
}
} finally {
if (null != in) {
in.close();
}
urlConnection.disconnect();
}
return str.toString();
}
}
In my opinion, it could be helpful for you if you use a library for http request.
I could suggest retrofit or volley.
Besides that, you could just try other methods to get the String from the InputStream, there is an interesting reply for that here
The one that I've used is
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
buf.write((byte) result);
result = bis.read();
}
return buf.toString();

Send HTTP POST - Android

I know that this has been asked but most are out dated, and method are deprecated. I have found this solution,
new Thread( new Runnable() {
#Override
public void run() {
try {
String query = "param=" +"item"+"&other="+"num";
URL url = new URL("http://www.url.com/url_post.php");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
//Set to POST
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setReadTimeout(10000);
Writer writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(query);
writer.flush();
writer.close();
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(TAG, e.toString());
}
}
}).start();
But, it does not provide how to get data that is returned for example, I am return some JSON, where get I get that data that is returned?
Thanks for the help :)
Do this
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
Finally in response you will get response JSON string then do what you want to do.
For more details visit this link
http://www.xyzws.com/javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139
I recommend you to use this project as library:
https://github.com/matessoftwaresolutions/AndroidHttpRestService
It's extremely easy and I use it for all my projects. I commited it to Github because it is difficult for me to find an easy Rest client for general purpose.
I'm going to commit an update for integration with Android Studio ASAP.
I hope it helps!!
InputStream in = connection.getInputStream();
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
Add this part after your writer.close()
connection.connect();
int statusCode = connection.getResponseCode();
Log.d("ON POST", " The status code is " + statusCode);
if (statusCode == 200) {
is = new BufferedInputStream(connection.getInputStream());
String response = convertInputStreamToString(is);
Log.d("ON POST", "The response is " + response);
return response;
} else {
Log.d("ON POST", "On Else");
return "";
}
The ConvertInputStreamToString() should be created to return your json as string
public static String convertInputStreamToString(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return response.toString();
}

Convert an inputstream to a string value in Java Android App

I'm having trouble with function(s) I'm writing. I'm trying to convert an inputstream to a string value. I've written two functions and I'm attempting to extract the String value but my Log.e response is returning NULL. Below is my syntax. What am I doing wrong? Thanks
public JSONArray GetCityDetails(String StateID) {
#SuppressWarnings("deprecation")
String url = "http://mywebsite.com/getCity.php?StateID="+URLEncoder.encode(StateID);
HttpEntity httpEntity = null;
try{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
httpEntity = httpResponse.getEntity();
} catch(ClientProtocolException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
JSONArray jsonArray = null;
if(httpEntity !=null){
try{
InputStream entityResponse = httpEntity.getContent();
// not working
String entityResponseAfterFunctionCall2 = readFully(entityResponse);
// not working
String entityResponseAfterFunctionCall3 = letsDoThisAgain(entityResponse);
Log.e("Entity Response Dude: ", entityResponseAfterFunctionCall3);
jsonArray = new JSONArray(entityResponseAfterFunctionCall3);
} catch(JSONException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
return jsonArray;
}
public String readFully(InputStream entityResponse) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = entityResponse.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString();
}
public String letsDoThisAgain(InputStream entityResponse){
InputStreamReader is = new InputStreamReader(entityResponse);
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(is);
try {
String read = br.readLine();
while(read !=null){
sb.append(read);
read = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
if(inputStream != null)
{
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(inputStream));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
else
{
return "";
}
Your readFully call will use your system's default character encoding to transform byte buffer into String. This is NOT what you want to happen.
You should use explicit character set in toString call. The encoding is usually specified in the HTTP request header.
Here is an example of how to convert a UTF-8 encoded string
return baos.toString( "UTF-8" );
Your second problem, is once you've consumed the InputString in readFully call, the letsDoThisAgain will not have anything to read, because the InputStream will be at the EOF.

Android POST Request 400 Response code throws Exception

When i send a POST Request to a Server, if the response is 200 i get the JSON body. However for unsuccessful requests the servers send a 400 response code but my android code throws a FileNotFoundException. Is there any difference between reading a 400 response and a 200 response ?
StringBuffer responseBuilder = new StringBuffer();
String line = null;
HttpURLConnection conn = null;
OutputStream out = null;
BufferedReader rd = null;
System.setProperty("http.keepAlive", "false");
try
{
conn = (HttpURLConnection) new URL(requestURL).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setConnectTimeout(NetworkConstants.CONNECTION_TIMEOUT);
conn.setReadTimeout(NetworkConstants.SOCKET_TIMEOUT);
out = conn.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
String s = formatParams();
Log.d("-------------------------------------------------->", s);
writer.write(s);
writer.flush();
writer.close();
}
catch (Exception e)
{
}
finally
{
if (out != null)
{
try
{
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
try
{
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null)
{
responseBuilder.append(line);
if (!rd.ready())
{
break;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (conn != null)
{
conn.disconnect();
}
}
String response = responseBuilder.toString();
Log.d("###########################", response);
return response;
Kind Regards,
Use getErrorStream() for this. From the docs:
If the HTTP response indicates that an error occurred, getInputStream() will throw an IOException. Use getErrorStream() to read the error response. The headers can be read in the normal way using getHeaderFields().
Sample code:
httpURLConnection.connect();
int responseCode = httpURLConnection.getResponseCode();
if (responseCode >= 400 && responseCode <= 499) {
Log.e(TAG, "HTTPx Response: " + responseCode + " - " + httpURLConnection.getResponseMessage());
in = new BufferedInputStream(httpURLConnection.getErrorStream());
}
else {
in = new BufferedInputStream(httpURLConnection.getInputStream());
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
urlResponse.append(line);
}
If the response code isn't 200 or 2xx, use getErrorStream() instead of getInputStream() to parse the json and show the message provided by your backend.
I know it's been a long time since the question was asked but for the benefit of other people who are still having this kind of problem please note that another possible cause of the problem is using "connection.getContent()" to get InputStream. like so:
InputStream is = (InputStream) connection.getContent();
this can create a problematic situation where response code larger than 399 will not be processed at all.
so the recommendation is to work directly with getInputStream() and getErrorStream() as shown in previous comments and as in the following example:
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
try {
String urlString = "http://www.someurl.com";
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream is;
int responseCode = connection.getResponseCode();
if (responseCode < HttpURLConnection.HTTP_BAD_REQUEST) {
is = connection.getInputStream();
} else {
is = connection.getErrorStream();
}
StringBuilder response = new StringBuilder();
bufferedReader = new BufferedReader(new InputStreamReader(is));
String tempLine;
while ((tempLine = bufferedReader.readLine()) != null) {
response.append(tempLine);
}
String serverResponse = response.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}

Categories

Resources