Android Jackson JSON Parser null value - android

I am using the Jackson JSON parser as I heard it was a lot more efficient than the default Android parser. I learned how to use it off this tutorial here
http://www.mkyong.com/java/jackson-streaming-api-to-read-and-write-json/
which is great tutorial if anyone wants to learn how to use Jackson json parser.
However, I am having an issue in that I can parse data fine in Java from a URL, however when I use Jackson with Android, I get null values or the screen just shows up black for some reason.
In order to retrieve the data from the website I am using this code from here
http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html
private InputStream retrieveStream(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
try {
HttpResponse getResponse = client.execute(getRequest);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error " + statusCode + " for URL " + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
return getResponseEntity.getContent();
}
catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
Then in my parse data method
InputStream source = retrieveStream(url);
try {
JsonFactory jfactory = new JsonFactory();
JsonParser jParser = jfactory.createJsonParser(source);
Then I parse data as was shown in the tutorial I linked above
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("Name".equals(fieldname)) {
jParser.nextToken();
this.setName(jParser.getText());
}
if ("Number".equals(fieldname)) {
jParser.nextToken();
this.setNumber(jParser.getText());
}
}
The url I am using is a dummy site set up which just has a JSON file on it which I am using to practice Jackson JSON parsing.
Now I know my parse data code is fine, as I in normal Java class, I can parse the data from the website using the code I created, and it works fine.
However if I try to use the code in Android with the code I have just shown, I just get a black screen for some odd reason. I have internet permissions enabled in manifest
Is there something wrong with the http code I have used? If so could someone show me how it should be done? And also why I am getting a black screen, I don't understand why it would show that.
Thanks in advance

Not sure if this is the problem, but your looping construct is unsafe: depending on kind of data you get, it is quite possible that you do not get END_OBJECT as the next token. And at the end of content, nextToken() will return null to indicate end-of-input. So perhaps you get into infinite loop with certain input?

I found the issue, the link was local host which could not be accessed from Emulator. Settings were changed, and can now access link, works perfectly now :D

Related

Android HttpPost request exception

Just as a demonstration the code will work, I am attempting to fetch some JSON data within my oncreate function. I know it should run on a different thread but I want to be sure the code successfully fetches my JSON before moving it into it's own thread.
The code is below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
/***************************************************/
final String TAG = "PostFetcher";
final String SERVER_URL = "http://kylewbanks.com/rest/posts";
// final String TAG = "PostsActivity";
// List<Post> posts;
try {
//Create an HTTP client
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(SERVER_URL);
//Perform the request and check the status code
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
try {
//Read the server response and attempt to parse it as JSON
Reader reader = new InputStreamReader(content);
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("M/d/yy hh:mm a");
Gson gson = gsonBuilder.create();
List<JsonObject> posts = new ArrayList<JsonObject>();
Log.e(TAG, "Checking: " + posts);
// posts = Arrays.asList(gson.fromJson(reader, JsonObject[].class));
content.close();
} catch (Exception ex) {
Log.e(TAG, "Failed to parse JSON due to: " + ex);
}
} else {
Log.e(TAG, "Server responded with status code: " + statusLine.getStatusCode());
}
} catch(Exception ex) {
Log.e(TAG, "Failed to send HTTP POST request due to: " + ex);
}
}
When I run the code, I get the second to last exception message:
Server responded with status code: 500
Can anyone please tell me what I'm doing wrong?
You are sending a HttpPost request to (obviously) an website that uses RESTful styled API.
This means, it works with HTTP Verbs (GET, POST, PUT, DELETE).
If you want to read data and the read access never changes data, use GET.
If you want to update or replace data, user PUT or POST (put usually to replace, POST to change/add). However, JavaScript does (or did) only support GET and POST requests, so keep that in mind.
If you want to delete a resource or collection, use DELETE.
That being said: If you want to load data, use Get in your case HttpGet instead of HttpPost.
Also read more about RESTful web APIs.
Edit:
In fact, calling the given URL in Fiddler2 (as stated in the comment on the other answer) results a HTML website reporting the error:
You called this URL via POST, but the URL doesn't end in a slash and
you have APPEND_SLASH set. Django can't redirect to the slash URL
while maintaining POST data. Change your form to point to
kylewbanks.com/rest/posts/ (note the trailing slash), or set
APPEND_SLASH=False in your Django settings.
Its internal server error..check if there are any exceptions are getting thrown at server side.
It has nothing to do with your android code, the problem is at server.
You can use AsyncTask to run network/filesystem related operations.

What are the best methods to consume a web service from android?

Can anyone tell me which is the best, ease and flexible method to consume web service from android? I'm using eclipse.
Since you only care about consuming a webservice, I assume you already know how to send data from the web server. Do you use JSON or XML, or any other kind of data format?
I myself prefer JSON, especially for Android.
Your question still lacks some vital information.
I personally use apache-mime4j and httpmime-4.0.1 libraries for web services.
With these libraries I use the following code
public void get(String url) {
HttpResponse httpResponse = null;
InputStream _inStream = null;
HttpClient _client = null;
try {
_client = new DefaultHttpClient(_clientConnectionManager, _httpParams);
HttpGet get = new HttpGet(url);
httpResponse = _client.execute(get, _httpContext);
this.setResponseCode(httpResponse.getStatusLine().getStatusCode());
HttpEntity entity = httpResponse.getEntity();
if(entity != null) {
_inStream = entity.getContent();
this.setStringResponse(IOUtility.convertStreamToString(_inStream));
_inStream.close();
Log.i(TAG, getStringResponse());
}
} catch(ClientProtocolException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
_inStream.close();
} catch (Exception ignore) {}
}
}
I make a request via _client.execute([method], [extra optional params])
The result from the request is put in a HttpResponse object.
From this object you can get the status code and the entity containing the result.
From the entity I take the content. The content would in my case be the actualy JSON string. You retrieve this as an InputStream, convert the stream to a string and do whatever you want with it.
For example
JSONArray result = new JSONArray(_webService.getStringResponse()); //getStringResponse is a custom getter/setter to retrieve the string converted from an inputstream in my WebService class.
Depending on how you build your JSON. mine is nested deeply with objects in the array etc.
But handling this is basic looping.
JSONObject objectInResult = result.getJSONObject(count);//count would be decided by a while or for loop for example.
You can extract data from the current JSON object in this case like:
objectInResult.getString("name"); //assume the json object has a key-value pair that has name as a key.
to parse "JSON" I recommend the following library is the faster and better.
Jackson Java JSON-processor

How to perform syncing in android?

I am creating a networking website's Application in android.I want to know how can I perform syncing ie I want to store all user contacts on websites to my android phone.
user's details will come in XML format.
Please Guide me ..
For that you have to make a web service call either by using HttpClient or by using other third-party libraries like kSoap2. But i would prefer native class instead of third-party library.
Here is a best example: http://lukencode.com/2010/04/27/calling-web-services-in-android-using-httpclient/
After making a call, you will receive a XML, after that you can parse the received XML response either by using SAX parser, Pull Parser or DOM Parser.
This is the scenario to fetch data from web to your local database.
For your info: To get response from Web:
public static InputStream getInputStreamFromWeb(String url) {
InputStream content = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(url));
content = response.getEntity().getContent();
} catch (Exception e) {
Log.("GET", "Network exception", e);
}
return content;
}

Android Send data back to server

How would one go about sending data back to server, from an android application?
I've already tried using HttpPost and posted back to a RESTful WCF service, but I couldnt get that to work (I've already created a SO question about this, without finding the solution..) - No matter what I do I keep getting 405 Method not allowed or the 400 Bad Request.. :(
I'm not asking for full code example necessarily.. just a pointer in a direction, which can enable me to send data back to a server.
It is important that the user should not have to allow or dismiss the transfer.. it should happen under the covers, so to speak
Thanks in advance
Services is the way to go. REST (I recommend this one on Android), or SOAP based. There're loads of tutorials on getting an android app communicate a service, even with .net / wcf ones.
Tho you can always just open raw sockets and send data with some custom protocol.
Edit:
Here's the doInBackground part of my asynctask handling http post communication, maybe that'll help:
protected String doInBackground(String... req) {
Log.d(TAG, "Message to send: "+req[0]);
HttpPost p = new HttpPost(url);
try{
p.setEntity(new StringEntity(req[0], "UTF8"));
}catch(Exception e){
e.printStackTrace();
}
p.setHeader("Content-type", "application/json");
String response = "";
try{
HttpResponse resp = hc.execute(p, localContext);
InputStream is = resp.getEntity().getContent();
response = convertStreamToString(is);
Log.d("Response", "Response is " + response);
} catch (Exception e){
e.printStackTrace();
}
return response;
}

UTF8 Encoding in Android when invoking REST webservice

I'm invoking a rest WS that returns XML. Some elements have strings include special characters like áãç etc...
When I get the information via browser all of it is shown properly but when invoking it from Android I don't get the proper special characters.
Notice the 'decoded' and 'encoded' variables:
when I use
URLDecoder.decode(result, "UTF-8")
The result stays the same
when I use
URLEncoder.encode(result, "UTF-8") The result changes to what it would be expected (full of %'s symbols and numeric representing symbols and special characters).
Here's the method to call the webservice:
public void updateDatabaseFromWebservice(){
// get data from webservice
Log.i(TAG, "Obtaining categories from webservice");
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(ConnectionProperties.CATEGORIES_URI);
ResponseHandler<String> handler = new BasicResponseHandler();
String result = "";
String decoded;
String encoded;
try {
result = client.execute(request, handler);
decoded = URLDecoder.decode(result, "UTF-8");
encoded = URLEncoder.encode(result, "UTF-8");
String c = "AS";
} catch (Exception e) {
Log.e(TAG, "An error occurred while obtaining categories", e);
}
client.getConnectionManager().shutdown();
}
Any help would be appreciated
Use this to get xml string, assuming the server encodes data in UTF-8:
HttpResponse response = client.execute(request);
... // probably some other code to check for HTTP response status code
HttpEntity responseEntity = response.getEntity();
String xml = EntityUtils.toString(responseEntity, HTTP.UTF_8);
Uh. URLDecoder and encoder are for encoding and decoding URLs, not XML content. It is used for URL you use when making requests. So code is just... wrong.
But even bigger issue is that you are taking a String, whereas content is really XML which needs to be parsed. And for parser to do proper decoding of UTF-8 (and handling of entities etc), you would be better of getting a byte[] from request, passing that to parser; although asking http client to do decoding may work ok (assuming service correctly indicates encoding used; not all do -- but even if not, XML parsers can figure it out from xml declaration).
So: remove URLDecoder/URLEncoder stuff, parser XML, and extract data you want from XML.

Categories

Resources