I've been trying to get a simple android client server app working, and I've had nothing but trouble. I'm hoping someone can look at this code and see what I'm doing wrong, maybe I'm doing things in the wrong order, or forgetting something? Just adding the relevant parts
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.addRequestProperty("Content-Type", "application/json");
// set some made up parameters
String str = "{'login':'superman#super.com','password':'password'}";
byte[] outputInBytes = str.getBytes("UTF-8");
OutputStream os = conn.getOutputStream();
os.write( outputInBytes );
os.close();
// connection.setDoOutput(true); //should trigger POST - move above -> crash
conn.setRequestMethod("POST"); // explicitly set POST -move above so we can set params -> crash
conn.setDoInput(true);
The error I get is
'exception: java.net.ProtocolException: method does not support a
request body: GET'
If I just do a POST request without parameters it's fine, so I guess I should move the connection.setDoOutput(true); or conn.setRequestMethod("POST"); higher up, that should work right? When I do that I get the error:
exception: java.net.ProtocolException: Connection already established.
So, if I try to set to POST before adding parameters it doesn't work, if I try to do it after it doesn't work... what am I missing? Is there another way I should be doing this? Am I adding parameters incorrectly? I've been searching for a simple android networking example, and I can't find any, is there any example the official Android site? All I want to do is a very basic network operation, this is so frustrating!
EDIT: I need to use HttpsURLConnection for reasons not included in the above code- I need to authenticate, trust hosts, etc- so I'm really looking for a potential fix for the above code if possible.
Here is an example of how to post with a JSON Object:
JSONObject payload=new JSONObject();
try {
payload.put("password", params[1]);
payload.put("userName", params[0]);
} catch (JSONException e) {
e.printStackTrace();
}
String responseString="";
try
{
HttpPost httpPost = new HttpPost("www.theUrlYouQWant.com");
httpPost.setEntity(new StringEntity(payload.toString()));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpResponse response = new DefaultHttpClient().execute(httpPost);
responseString = EntityUtils.toString(response.getEntity());
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
And example of how to get
String responseString = "";
//check if the username exists
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("www.theUrlYouQWant.com");
ArrayList<String> existingUserName = new ArrayList<String>();
try
{
HttpResponse response = client.execute(httpGet);
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);
}
}
else
{
Log.e(ParseException.class.toString(), "Failed to download file");
}
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
I followed this tutorial on making http calls:
http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
Works fine with no problems.
Below is a class that I have modified from the sample:
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
String TAG = ((Object) this).getClass().getSimpleName();
public ServiceHandler() {
}
/**
* Making service call
*
* #url - url to make request
* #method - http request method
*/
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/**
* Making service call
*
* #url - url to make request
* #method - http request method
* #params - http request params
*/
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 2000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
Log.e("Request: ", "> " + url);
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
if (httpResponse != null) {
httpEntity = httpResponse.getEntity();
} else {
Log.e(TAG, "httpResponse is null");
}
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
And this is how I use the class:
nameValuePairs = new ArrayList<NameValuePair>();
String param_value = "value";
String param_name = "name";
nameValuePairs.add(new BasicNameValuePair(param_name, param_value));
// Creating service handler class instance
sh = new ServiceHandler();
String json = sh.makeServiceCall(Utils.getUrl, ServiceHandler.GET, nameValuePairs);
Related
I am fairly confident this code works (I used it in another part of my project for a different API) as far as posting but I do not think the URL is being formatted correctly. I want to know if there is anyway to view the full URL after building all of the entities so I can see if the final URL is formatted correctly. Code:
My URL = http://pillbox.nlm.nih.gov/PHP/pillboxAPIService.php
Method = POST
API key = not going to post (works though)
drugName = just a string that has the name of a drug
I have logs in the code to try and view the url but they aren't returning anything close and the debugger isn't either.
I am trying to build the URL to look like this:
http://pillbox.nlm.nih.gov/PHP/pillboxAPIService.php?key=My_API_KEY&ingredient=diovan
public String makeServiceCallPillBox(String url, int method,
String api, String drugName)
{
String resultEnitity = null;
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = null;
HttpEntity entityResult = null;
// Checking http request method type
if (method == POST)
{
HttpPost httpPost = new HttpPost(url);
// Butild the parameters
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addTextBody("key", api);
builder.addTextBody("ingredient", drugName);;
final HttpEntity entity = builder.build();
httpPost.setEntity(entity);
Log.d("url", httpPost.toString());
httpResponse = httpClient.execute(httpPost);
Log.d("post", builder.toString());
Log.d("post2", entity.toString());
entityResult = httpResponse.getEntity();
resultEnitity = EntityUtils.toString(entityResult);
Log.d("result", resultEnitity);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return resultEnitity;
}
Any help is appreciated.
I'm trying to make a post to a node.js server but for some reason the body is always empty for me no matter what I try.
I'm testing now towards requestb.in and its always empty there too.
This is the code I use for posting:
public static String post(String url, String json) {
StringBuilder stringBuffer = new StringBuilder();
BufferedReader bufferedReader = null;
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost("http://requestb.in/14a9s7m1");
StringEntity se = new StringEntity("{'string':'string'}", HTTP.UTF_8);
se.setContentType("application/json; charset=UTF-8");
httpPost.setEntity(se);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("hmac", Methods.getMethods().getHmac(json));
HttpResponse httpResponse = httpClient.execute(httpPost, localContext);
InputStream inputStream = httpResponse.getEntity().getContent();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String readLine = bufferedReader.readLine();
while (readLine != null) {
stringBuffer.append(readLine);
stringBuffer.append("\n");
readLine = bufferedReader.readLine();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringBuffer.toString();
}
This is the requestb.in http://requestb.in/14a9s7m1?inspect
raw body should contain the json string, right?
Any suggestions?
You can make many mistakes when using HttpUrlConnection. I admit that I don't see any error, but this doesn't mean anything.
Since Google doesn't recommend using HttpClient and AndroidHttpClient (except for FROYO or older), but we should use HttpUrlConnection instead, you're on the right way (from a Android perspective).
When using a very lightweight wrapper for HttpUrlConnection called DavidWebb, the code looks like this (I left out hmac-generation):
public class TestWebbRequestBin {
#Test public void stackOverflow20543115() throws Exception {
Webb webb = Webb.create();
webb.setBaseUri("http://requestb.in");
JSONObject jsonObject = new JSONObject();
jsonObject.put("string", "string");
String json = jsonObject.toString(); // {"string":"string"}
Response<String> response = webb
.post("/1g7afwn1")
.header("Accept", "application/json")
.header("Content-type", "application/json")
.header("hmac", "some-hmac-just-a-test")
.body(json)
.asString();
assertEquals(200, response.getStatusCode());
assertTrue(response.isSuccess());
String body = response.getBody();
assertEquals("ok\n", body);
}
}
When the JSON I post looks like in your example, requestb.in does accept it:
json = "{'string':'string'}";
But this is not valid JSON (here tested in node.js):
> JSON.parse("{'string':'string'}")
SyntaxError: Unexpected token '
at Object.parse (native)
at repl:1:7
at REPLServer.self.eval (repl.js:110:21)
at Interface.<anonymous> (repl.js:239:12)
tl;dr
Take care to send valid JSON
Master HttpUrlConnection or use a simple abstraction library
For nasty bugs you could either debug your node.js code (or console.log(req)) or use a tool like Wireshark.
Try this code to send the string.... In HttpPost you should use key value pairs to send the data.
HttpPost httppost = new HttpPost(SERVER_URL);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("REQUEST", req));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
I am not sure is this the problems. Can you give a tried?
You are sending invalid JSON format string. This make server unable to accept your invalid json string so your body is empty. To solve this, change following code.
StringEntity se = new StringEntity("{\"string\":\"string\"}", HTTP.UTF_8);
I couldn't get HttpPost to work, but HttpUrlConnection works instead. It solves my problem, but doesn't solve the mysterious no body thing of httpPost.
Here is my solution:
public static String post(String ur2l, String json) {
StringBuilder stringBuffer = new StringBuilder();
BufferedReader bufferedReader = null;
try {
URL url = new URL(ur2l);
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Content-type", "application/json");
conn.setRequestProperty("hmac", Methods.getMethods().getHmac(json));
conn.setDoOutput(true);
OutputStream os = null;
try {
os = conn.getOutputStream();
os.write(json.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
os.close();
conn.connect();
int respCode = conn.getResponseCode();
if (respCode == 200) {
InputStream inputStream = conn.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String readLine = bufferedReader.readLine();
while (readLine != null) {
stringBuffer.append(readLine);
stringBuffer.append("\n");
readLine = bufferedReader.readLine();
}
}
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringBuffer.toString();
}
I can't parse Arabic/Persian text from SQL database. Everything is set to UTF-8. My SQL database text is set to utf8_general_ci. JSON parser is set to UTF-8 too.
Text is shown good in English. But when I use Arabic/Persian text in database, android shows text as ???????.
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET method
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
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();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
I have been r & d around a day and finally success to parse my arabic json response getting from server using following code.So, may be helpful to you.
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
params.setBooleanParameter("http.protocol.expect-continue", false);
HttpClient httpclient = new DefaultHttpClient(params);
HttpPost httppost = new HttpPost(Your_URL);
HttpResponse http_response= httpclient.execute(httppost);
HttpEntity entity = http_response.getEntity();
String jsonText = EntityUtils.toString(entity, HTTP.UTF_8);
Log.i("Response", jsonText);
Now, use jsonText for your further requirement.
Thank You
Maybe the problem is on server side. Check the raw String you got from the Server to see if it is correctly formatted.
I think it can help you by storing it as clob/blob, since once you have the bytes which were convereted from UTF-8 at server side, any client side code can also then using various String encoding formats to display the test.
Or my other advice, use a webview to display it, its more mature to handle these nuances.
I am writing an Android program that needs to access a URL with GET variables which will be logged into a database. All I need to do is open a URL so the web server will log the data! How should I go about this?
Thanks
// default HTTP Client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Use this.
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("URL HERE"));
startActivity(browserIntent);
Hope this helps.
EDIT:
Ok, use this. It calls the URL without opening a browser
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("URL HERE");
HttpResponse response = httpClient.execute(httpGet, localContext);
You can also use HttpUrlConnection. Sample code -
// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string.
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
And obviously since it is a netowork call you cannot do it in main/UI thread. So you can do it in async task. More details and Source
I need to do a HTTP post to a web service..
If I place this into a web browser like this
http://server/ilwebservice.asmx/PlaceGPSCords?userid=99&longitude=-25.258&latitude=25.2548
then is stores the values to our DB on the server..
In Eclipse, using Java programming for android.. The url will look like
http://server/ilwebservice.asmx/PlaceGPSCords?userid="+uid+"&longitude="+lng1+"&latitude="+lat1+"
with uid, lng1 and lat1 being assigned as strings..
How would I run this?
Thanks
try {
HttpClient client = new DefaultHttpClient();
String getURL = "http://server/ilwebservice.asmx/PlaceGPSCords?userid="+uid+"&longitude="+lng1+"&latitude="+lat1+";
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
//do something with the response
Log.i("GET RESPONSE",EntityUtils.toString(resEntityGet));
}
} catch (Exception e) {
e.printStackTrace();
}
For http post use name value pair. See below code -
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("longitude", long1));
nameValuePairs.add(new BasicNameValuePair("latitude", lat1));
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePair));
HttpResponse response = httpclient.execute(httppost);
Infact I had done already what you are going to do. So try this stff. You can create a method like this what I have and pass your URL with lat, long. This is return you the response of the HTTP connection.
public static int sendData(String url) throws IOException
{
try{
urlobj = new URL(url);
conn = urlobj.openConnection();
httpconn= (HttpURLConnection)conn;
httpconn.setConnectTimeout(5000);
httpconn.setDoInput(true);
}
catch(Exception e){
e.printStackTrace();}
try{
responseCode = httpconn.getResponseCode();}
catch(Exception e){
responseCode = -1;
e.printStackTrace();
}
return responseCode;
}
I'm not sure I understood your question, but if I did I think you can use java.net.UrlConnection :
URL url = new URL("http://server/ilwebservice.asmx/PlaceGPSCords?userid="+uid+"&longitude="+lng1+"&latitude="+lat1);
URLConnection conn = url.openConnection();
conn.connect();