Android BufferedInputStream HTTP POST/GET - android

I Use BufferedInputStream For HTTP POST/GET
But I Get Some Error the Below
java.io.FileNotFoundException: http://XX.XX.XX.XX/WebWS/data.aspx
Transport endpoint is not connected
Why Get This Error. My Code is Below
URL url = new URL(glob.postUrl);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
try {
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
httpConn.setRequestProperty("Content-Language", "TR");
httpConn.setConnectTimeout(12000);
Iterator<String> reqProps = hMap.keySet().iterator();
while (reqProps.hasNext()) {
String key = reqProps.next();
String value = hMap.get(key);
httpConn.addRequestProperty(key, value);
}
InputStream in = new BufferedInputStream(httpConn.getInputStream());
StringBuilder builder = new StringBuilder();
String line;
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, "UTF-8"));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} finally {
in.close();
}
httpConn.disconnect();
Thanks.

Is there any reason you're not using HttpClient?
You can replace your code with something like:
HttpContext httpContext = new BasicHttpContext();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet, httpContext);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String page = EntityUtils.toString(entity);
You can setup the HttpClient with ClientConnectionManager and HttpParams for security and various http parameters for the client at initialisation (plenty of examples around if you search on class names).

HttpURLConnectionImpl.getInputStream() is known to throw a FileNotFoundException if the HTTP response status code is 400 or higher, i.e. for any error condition on the server side. You should check what the status code really is in order to obtain suitable debug information.
However, I second Mark Fisher's suggestion about using HttpClient, which AFAIK is the preferred way of working with HTTP on Android.

Related

401 unauthorized error for GET request with type Authorization = bearer token

I am making an HttpGet request with "Authorization" as header attaching bearer token. I am getting a 401 unauthorized error all the time.
I have tried retrofit, it didn't work so I reverted back to basic HTTP client. Then after a lot of research found that there is some error with DefaultHttp. So I changed to HTTPUrlConnection. Even after doing all these, I am still getting an unauthorized 401 error. What could I possibly do wrong here? Because this error still persists, I decided to stick to HTTPUrlConnection or DefaultHTTP and stay away from libraries.
Here is my code with HttpUrlConnection
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection)
obj.openConnection();
con.setRequestMethod("GET");
String authString = "Bearer" + accessToken;
con.setRequestProperty("Authorization", authString);
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
} else {
System.out.println("GET request not worked");
}
Here is my DefaultHttp request
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGetRequest = new HttpGet(url);
httpGetRequest.addHeader("Authorization","Bearer"+accessToken);
try {
HttpResponse response = client.execute(httpGetRequest);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new
InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
add a whitespace after Bearer cus as it stands your concatenating Bearer with the token as one string
Please use Fast Android Networking library its very easy to use and you can implement your logic in less than 5 mins. So please give it a try atleast. Below is the link to library:
https://github.com/amitshekhariitbhu/Fast-Android-Networking
The problem was resolved. I tried using retrofit and defaultHttpClient but both didn't worked for me because of some cookie issue. But using OKHttpClient it was straight forward and I was able to hit the server and get the response.
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(mURL)
.addHeader("Authorization", String.format("Bearer %s", bearerToken))
.build();
Response response = client.newCall(request).execute();
return response.body().string();

Android send POST request in Java to ASP.net Web API

When I used HttpUrlConnection to send POST request from Android to ASP.net Web API. It seems not working.
String baseUrl = "http://<IP Address>/Save/Document";
URL url = new URL(baseUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
JSONObject ap = new JSONObject();
// Where data is a JSON string
// Like [{Test: 1}, {Test: 2}]
ap.put("",new Gson().toJson(data));
OutputStreamWriter ap_osw= new OutputStreamWriter(conn.getOutputStream());
ap_osw.write(ap.toString());
ap_osw.flush();
ap_osw.close();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
StringBuilder response = new StringBuilder();
while ((output = br.readLine()) != null) {
response.append(output);
response.append('\r');
}
String mes = response.toString();
Log.i("INFO", mes);
conn.disconnect();
When executing the above code, it will have an FileNotFoundException in
conn.getInputStream()
I also tried to implement source code in HttpClient style.
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(baseUrl);
try {
StringEntity se = new StringEntity((new Gson()).toJson(data));
httpPost.setEntity(se);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-Type", "application/json");
HttpResponse response = httpClient.execute(httpPost);
InputStream inputStream = response.getEntity().getContent();
String result = "";
if (inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
Log.i("RESPONSE", result);
} catch (Exception ex) {
Log.i("Exception", ex.getMessage());
}
return output;
And this time, it shows "The requested resource does not support http method 'get'".
I have no ideas how to implement the POST request method to send data from Android to ASP.net Web API. Any recommendations?
Finally, the following coding is my ASP.net Web API for reference.
[HttpPost]
[Route("Save/Document")]
public HttpResponseMessage Post([FromBody]string model)
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Content = new StringContent(model, System.Text.Encoding.UTF8, "text/plain");
return resp;
}
Finally, I got a solution to fix this problem. It is due to the POST data in request body can not be read from Web API.
When the request Content-Type is "application/json",
Using string, The request body should be a plain text (e.g. "Text Message").
[FromBody] string inStr
Using self-defined class, The request body should be a json string
(e.g { KEY: VALUE })
[FromBody] YourClass inObj
Using array of self-defined class, The request body should be a json array string (e.g [{ KEY: VALUE }])
[FromBody] YourClass[] inObj
And the self-defined class should be like as following:-
class YourClass {
public string KEY { get; set; }
}
Btw. Thanks for all reply and useful information.

Passing cookie with an HTTT GET

I am trying to get a list of user subreddits via the reddit api. Currently I am able to do a post for login which returns a cookie and modhash. Those are the parameters I'm passing to my method below. However each time I call the function I get an empty response:
"{}"
How can I pass a cookie and modhash via HTTPGET to get a valid response?
public void getUserSubreddits(String[] loginInfo){
HttpClient client = new DefaultHttpClient();
URL url = null;
try {
url = new URL("http://www.reddit.com/subreddits/mine/.json?limit=100");
HttpGet httpGet = new HttpGet(String.valueOf(url));
client.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
httpGet.addHeader("cookie", loginInfo[1]);
httpGet.addHeader("modhash", loginInfo[0]);
HttpResponse response = client.execute(httpGet);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
Log.d(TAG,total.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
It was a simple mistake. To anyone in the future trying this I solved the problem by using Chrome to inspect the headers of an active session on http://www.reddit.com/subreddits/mine/.json?limit=100 url and found that the cookie header started with:
reddit_session
So I removed the modhash changed the my header parameter to read:
httpGet.addHeader("cookie", "reddit_session="+loginInfo[1]+";");
With this I got a valid response.

Cannot change CONTENT_TYPE to application/x-www-form-urlencoded in Android HTTP POST call

Our server expects 'application/x-www-form-urlencoded' content-type on POST calls but when I set the header to 'application/x-www-form-urlencoded', it returns a 400 Bad Request. Here's my code using HttpPost:
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=UTF-8");
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse responseobj = httpClient.execute(httpPost);
InputStream is = null;
HttpEntity entity = responseobj.getEntity();
is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
Here's my code using HttpsUrlConnection:
URL urlToRequest;
urlToRequest = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) urlToRequest.openConnection();
String postParams = getEncodedPostParams(params);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setFixedLengthStreamingMode(postParams.getBytes().length);
conn.setRequestProperty(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=UTF-8");
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(postParams);
writer.close();
os.close();
conn.connect();
Here's the request on Charles Proxy. You can see that although I have set the content-type to 'application/x-www-form-urlencoded' in both cases, the request content-type is 'application/json':
https://myurl/
Complete
400 Bad Request
HTTP/1.1
POST
application/json
Does anyone know why I cannot change the content-type? I know similar questions have been asked before on SO and I have tried all of them to no avail. Your help would be greatly appreciated.
Thanks!
Why don't use:
con.setRequestProperty("Content-Type",....)
it worked for me.

Difference between URLConnection getInputStream() & HttpEntity getContent()

I try to download pic from the specific url, firstly I use this way to get InputStream:
if (url != null) {
URLConnection ucon = null;
try {
ucon = url.openConnection();
} catch (IOException e2) {
e2.printStackTrace();
}
if (ucon != null) {
ucon.setConnectTimeout(CONN_TIMEOUT);
ucon.setReadTimeout(READ_TIMEOUT);
try {
is = ucon.getInputStream();
It works good, but when I try to download pic from http://111.12.12.232/images/face/bigface/339.gif
I can't get the InputStream, but try to use :
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
HttpProtocolParams.setUseExpectContinue(params, false);
HttpConnectionParams.setConnectionTimeout(params, CONN_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, READ_TIMEOUT);
HttpGet getRequest;
try {
getRequest = new HttpGet(url.toURI());
HttpClient client = new DefaultHttpClient(params);
HttpResponse response = client.execute(getRequest);
HttpEntity entity = response.getEntity();
is = entity.getContent();
This way can get InputStream successfully, and can download the gif.
So I wonder what's the different between the two methods?
Thanks~
It looks like the server returns the image content but also returns a 404 response code, which indicates an error fulfilling the request.
On the 1.6 Sun/Oracle JDK, the HttpURLConnection seems to fail with an IOException when it notices a return code like this, and does not attempt to return content. My guess is that the Android platform has this same behavior, and the Apache HttpClient library you used is a bit more robust to server misconfigurations.

Categories

Resources