I'm basically trying to pass a List<NameValuePair> to an external class that handles POST HTTPRequest on an Android app.
String[] args = new String[]{"http://url/login", nameValuePairs.toString()}; //nameValuePairs is a param list to send via POST
Log.i("params", nameValuePairs.toString());
try {
String text = new rest().execute(args).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The doInBackgroud of the ASyncTask receives two parameters (the url for the request and the result of nameValuePairs.toString()), and I cannot find a way to convert the string back to a List< NameValuePair >.
Any ideas?
I bring you an example of how to consume REST services by POST or GET, sets the List< NameValuePair > as parameters and then parse the response to a string that can then be used as suits you (JSON, XML, or a data frame)
import java.io.*;
import java.util.*;
import org.apache.http.*;
import org.apache.http.client.*;
import org.apache.http.client.entity.*;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.*;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
public class RESTHelper {
private static final String URL_POST = "http://url/login";
private static final String URL_GET = "http://url/login";
public static String connectPost(List<BasicNameValuePair> params){
String result = "";
try{
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(URL_POST);
request.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
}
}catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static String connectGet(List<BasicNameValuePair> params){
String result = "";
try{
String finalUrl = URL_GET + URLEncodedUtils.format(params, null);
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(finalUrl);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
}
}catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
private static String convertStreamToString(InputStream is) {
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();
}
}
You can't, unless you write some sort of converter that pulls apart a known format, e.g., nvp[0].name=xxx, nvp[0].value=zzz etc. or re-structures the default toString output (not fun).
Normally you'd use JSON, XML, etc. instead of List.toString.
Or use an actual HTTP client library.
If you execute a code like this:
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
....
List<NameValuePair> h = new ArrayList<NameValuePair>();
h.add(new BasicNameValuePair("a", "b"));
h.add(new BasicNameValuePair("c", "d"));
Log.d("jj", h.toString());
you can see that the output is something like:
[a=b, c=d]
so you can write a parser (or maybe using split()) to restore the List.
However I think it's not a good idea to rely on the implementation of toString in ArrayList and NameValuePair, and use another kind of serialization method, like JSON as Dave said.
Related
I am trying to use an API from https://us.mc-api.net/ for a project and I have made this as a test.
public static void main(String[] args){
try {
URL url = new URL("http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
System.out.println("I/O Error");
}
}
}
And this is giving me an IOException error but when ever I open the same page in my web browser I get
false,Unknown-Username
which is what I want to get from the code. I am new and don't really know why it is happening or why.
EDIT: StackTrace
java.io.FileNotFoundException: http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.URL.openStream(Unknown Source)
at com.theman1928.Test.Main.main(Main.java:13)
The URL is returning status code 404 and therefore the input stream (mild guess here) is not being created and therefore is null. Sort the status code and you should be OK.
Ran it with this CSV and it is fine: other csv
If the error code is important to you then you can use HttpURLConnection:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
System.out.println("code:"+conn.getResponseCode());
In that way you can process the response code before proceeding with a quick if-then-else check.
I tried it with the Apache HTTP libraries. The API endpoint seems to return a status code of 404, hence your error. Code I used is below.
public static void main(String[] args) throws URISyntaxException, ClientProtocolException, IOException {
HttpClient httpclient = HttpClients.createDefault();
URIBuilder builder = new URIBuilder("http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
HttpResponse response = httpclient.execute(request);
System.out.println(response.getStatusLine().getStatusCode()); // 404
}
Switching out the http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/ with www.example.com or whatever returns a status code of 200, which further proves an error with the API endpoint. You can take a look at [Apache HTTP Components] library here.
This has to do with how the wire protocols are working in comparison with the java.net classes and an actual browser. A browser is going to be much more sophisticated than the simple java.net API you are using.
If you want to get the equivalent response value in Java, then you need to use a richer HTTP API.
This code will give you the same response as the browser; however, you need to download the Apache HttpComponents jars
The code:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.HttpClients;
public class TestDriver
{
public static void main(String[] args)
{
try
{
String url = "http://us.mc-api.net/v3/uuid/193nonaxishsl/csv";
HttpGet httpGet = new HttpGet(url);
getResponseFromHTTPReq(httpGet, url);
}
catch (Throwable e)
{
e.printStackTrace();
}
}
private static String getResponseFromHTTPReq(HttpUriRequest httpReq, String url)
{
HttpClient httpclient = HttpClients.createDefault();
// Execute and get the response.
HttpResponse response = null;
HttpEntity entity = null;
try
{
response = httpclient.execute(httpReq);
entity = response.getEntity();
}
catch (IOException ioe)
{
throw new RuntimeException(ioe);
}
if (entity == null)
{
String errMsg = "No response entity back from " + url;
throw new RuntimeException(errMsg);
}
String returnRes = null;
InputStream is = null;
BufferedReader buf = null;
try
{
is = entity.getContent();
buf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
StringBuilder sb = new StringBuilder();
String s = null;
while (true)
{
s = buf.readLine();
if (s == null || s.length() == 0)
{
break;
}
sb.append(s);
}
returnRes = sb.toString();
System.out.println("Response: [" + returnRes + "]");
}
catch (UnsupportedOperationException | IOException e)
{
throw new RuntimeException(e);
}
finally
{
if (buf != null)
{
try
{
buf.close();
}
catch (IOException e)
{
}
}
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
}
}
}
return returnRes;
}
}
Outputs:
Response Code : 404
Response: [false,Unknown-Username]
W/System.err(27207): [DEBUG] GbaRequest - GbaRequest: Constructor Called 222 userAgent Apache-HttpClient/UNAVAILABLE (java 1.4)
Thank you in advance for the assistance. I wasn't able to find a post regarding this error I received on my project.
I receive this error only sometimes, though I'm not sure why it comes up as it seems random when it occurs. I don't notice anything out of the ordinary in my data input.
My android application is attempting to make a connection to a remote server and push data into the PostgreSQL tables. Would anyone be able to refer me to the proper documentation for this error or explain its meaning. I appreciate the assistance.
Here is my code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser
{
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
public JSONParser()
{
// Empty Constructor
}
public JSONObject getJSONFromUrl(String url)
{
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
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, "iso-8859-1"), 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
{
jObj = new JSONObject(json);
}
catch (JSONException e)
{
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
return jObj;
}
public JSONObject makeHttpRequest(String url, String method, List<NameValuePair> params)
{
try
{
if (method == "POST")
{
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
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")
{
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
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();
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 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 jObj;
}
}
That is not an error itself, Apache-HttpClient/UNAVAILABLE (java 1.4) is the default User Agent string for your Apache HttpClient.
This happens when you don't send the User Agent ("User-Agent:") via HTTP headers, then the phone GBA Service warn you about that.
If you want send the default system User Agent you can do
httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
this should be like
Dalvik/1.6.0 (Linux; U; Android 4.2.2; Galaxy Nexus Build/JDQ39)
or if you want sent a custom User Agent you can do
httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "My user agent");
or you can set the header via setHeader method
requestOrPost.setHeader("User-Agent", USER_AGENT);
I am having problems calling a simple JSON web service from an Android app. The .execute() completes successfully with an 200-OK Status however I am unable to read any JSON output or text.
For the record, if I HttpPost a regular webpage, like Google.com, I can read and parse all the markup. Also, I am able to call the complete urlWithParams string from the device's browser and I see JSON output in the browser. This works in device's browser:
http://maps.googleapis.com/maps/api/distancematrix/json?origins=Seattle&destinations=San+Francisco&mode=bicycling&language=fr-FR&sensor=false
When the code runs, the reader is always blank and reader.readLine() never runs. Returns an empty string. If I change the URL to Google.com, it works and returns 17,000 characters. Thanks!
protected String doInBackground(String... uri) {
String responseString = null;
try {
//String urlGoogle = "http://google.com";
//String urlWithParams = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=Seattle&destinations=San+Francisco&mode=bicycling&language=fr-FR&sensor=false";
String urlOnly = "http://maps.googleapis.com/maps/api/distancematrix/json";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(urlOnly);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("origins", "Seattle"));
nameValuePairs.add(new BasicNameValuePair("destinations", "Cleveland"));
nameValuePairs.add(new BasicNameValuePair("sensor", "false"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
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();
}
responseString = sb.toString();
}}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
Maybe you should test other mime types instead of application/json.
1 - Check in your manifest file having INTENET Permission or not.
2 - Use this code its returning data
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
try {
String inputLine;
while ((inputLine = reader.readLine()) != null) {
responseString += inputLine;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Solved! The blank return when calling the JSON page was due to not having the proxy settings defined. Proxy settings were setup on the device however per this post, HttpClient does NOT inherit them.
Adding the following line resolved my issue. The code is now returning JSON.
HttpHost proxy = new HttpHost("172.21.31.239", 8080);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
Trying to get the json from http request by using this class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
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, "iso-8859-1"), 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;
}
}
But some times getting the exception like
E/Buffer Error(300): Error converting result java.io.IOException: Attempted read on closed stream.
Can any one help on this thanks in advance.
try like this way..
HttpClient client = new DefaultHttpClient();
// Perform a GET request for a JSON list
HttpUriRequest request = new HttpGet("https://somejson.json");
// Get the response that sends back
HttpResponse response = null;
try {
response = client.execute(request);
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
thanks i changed the code to this:Now its double faster than before.
But i need to test more number of times since i was getting the exception which i posted as question very rarely.
public class JSONParser {
InputStream is = null;
JSONObject jObj = null;
String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
HttpClient client = new DefaultHttpClient();
// Perform a GET request for a JSON list
HttpUriRequest request = new HttpGet(url);
// Get the response that sends back
HttpResponse response = null;
try {
response = client.execute(request);
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
HttpEntity entity = response.getEntity();
try {
json = EntityUtils.toString(entity);
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
It was faster than before ,But problem is app crashing when its the network connection is slow.
I suggest removing the static. With me it worked after the removal.
static InputStream is = null;
At first i really don't like your static InputStream variable, why static? Just make it normal variable and not static. And especially in Android static variables are not a win at all.
And second if you want to get JSON from Server you need to use GET request instead of POST
And to question.
I think problem is that you should close BufferedReader rather than InputStream
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
reader.close();
// next work
And at the end one suggestion. What about to use EntityUtils instead of getContent(). You will save a time by it instead of reading from InputStream.
HttpEntity entity = response.getEntity();
String json = EntityUtils.toString(entity);
and now you have quickly JSON as String.
just make InputStream non-static that's all.
I used post method and just fine...
I need to send some data from my Android device to my server. I am doing this through JSON. I have implemented the JSON post on Android, and I am trying to do a mapping on the server side in order to retrieve that data. My problem is that I keep getting an empty string.
Android method used to send JSON:
private void sendJson(final String json, final String URL) {
Thread t = new Thread(){
public void run() {
Looper.prepare(); //For Preparing Message Pool for the child Thread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
try{
HttpPost post = new HttpPost(URL);
StringEntity se = new StringEntity(json);
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
client.execute(post);
}
catch(Exception e){
e.printStackTrace();
}
Looper.loop(); //Loop in the message queue
}
};
t.start();
}
Server-side method:
#RequestMapping(value = "/getLatestCalls", method = RequestMethod.POST)
public void getData(#ModelAttribute String json){
//... do something
}
The thing is that in this method my json String is "" every time. I have also tried using #RequestParam but with that it doesn't enter the method anymore. I have also tried with #ModelAttribute("json").
Can someone enlighten me a little here? Thank you in advance.
Here is the solution and it works fine.
server-side
#Controller
public class DataCollector {
#RequestMapping(value = "/clientdatacollector", method = RequestMethod.POST)
public #ResponseBody
void abc(Writer writer, #RequestParam("gpsdata") String gpsJSON) {
try {
// here is your jsonstring ;)
writer.write(gpsJSON.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
client-side
public static void httptest() {
ArrayList<TravellingData> tdArray = new ArrayList<TravellingData>();
Gson gson = new Gson();
String jsonString = "";
for (int i = 0; i < 1; i++) {
tdArray.add(ObjectCreater.createMockTravellingDataObject());
}
jsonString = gson.toJson(tdArray);
HttpClient client = new DefaultHttpClient();
HttpPost post = null;
try {
post = new HttpPost(
"http://localhost:8080/uygulama/clientdatacollector");
} catch (URISyntaxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("gpsdata", jsonString));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = null;
try {
response = client.execute(post);
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Try using #RequestBody. It should work.