Difficulty Parsing JSON with JQuery - java

I have developed an application to write twitter search results as JSON objects to a results page as such:
for (Status tweet : tweets) {
Map<String, String> tweetResult = new LinkedHashMap<String, String>();
tweetResult.put("username", tweet.getUser().getScreenName());
tweetResult.put("status", tweet.getText());
tweetResult.put("date", tweet.getCreatedAt().toString());
tweetResult.put("retweets", String.valueOf(tweet.getRetweetCount()));
String resultJson = new Gson().toJson(tweetResult);
response.getWriter().write(resultJson);
}
This is called with AJAX/JQuery in the following:
$(document).ready(function() {
$.getJSON('SearchServlet', function(list) {
var table = $('#resultsTable');
$.each(list, function(index, tweet) {
$('<tr>').appendTo(table)
.append($('<td>').text(tweet.username))
.append($('<td>').text(tweet.status))
.append($('<td>').text(tweet.date))
.append($('<td>').text(tweet.retweets));
});
});
});
With the intention of populating a table with the results:
<body>
<div id="wrapper">
<div id="contentArea">
<div id="content">
<h2>Results:</h2>
<table id="resultsTable"></table>
</div>
</div>
</div>
</body>
The GET call is working perfectly and the results show up in the firebug console without a problem, however they're not appearing on the actual document itself as intended. I've tried a number of different approaches to this (including the answers here and here ).
Example of the JSON output:
{"username":"Dineen_","status":"RT #TwitterAds: Learn how to put Twitter to work for your small business! Download our small biz guide now: https://t.co/gdnMMYLI","date":"Tue Feb 26 08:37:11 GMT 2013","retweets":"22"}
Thanks in advance.

It seems your serialization is wrong. Since you are generating a sequence of concatenated JSON objects not enclosed properly in an array.
Current invalid JSON response:
{ ... } { ... } { ... } { ... }
Whereas the expected JSON response should be:
[ { ... }, { ... }, { ... }, { ... } ]
No need to do this by hand. Gson may do it automatically for you if you construct the proper object. For example, using something as follows (untested):
List<Map<String, String>> tweetList = new LinkedList<Map<String, String>>();
for (Status tweet : tweets) {
Map<String, String> tweetResult = new LinkedHashMap<String, String>();
tweetResult.put("username", tweet.getUser().getScreenName());
tweetResult.put("status", tweet.getText());
tweetResult.put("date", tweet.getCreatedAt().toString());
tweetResult.put("retweets", String.valueOf(tweet.getRetweetCount()));
tweetList.add(tweetResult);
}
String resultJson = new Gson().toJson(tweetList);
response.getWriter().write(resultJson);
After this fix you should be able to use your original code.
Based on your example JSON output the returned output is an Object, not an Array. You don't need to use $.each here.
$(document).ready(function () {
$.getJSON('SearchServlet', function(tweet) {
var table = $('#resultsTable');
$('<tr>').appendTo(table)
.append($('<td>').text(tweet.username))
.append($('<td>').text(tweet.status))
.append($('<td>').text(tweet.date))
.append($('<td>').text(tweet.retweets));
});
});

I think the issue is with your use of $.each. Since you are passing in an object, each is iterating over the key-value pairs of the object. (see http://api.jquery.com/jQuery.each/)
You might want to return a JSON object that is wrapped in square brackets, just so it iterates over an array.
[{"username":"Dineen_","status":"RT #TwitterAds: Learn how to put Twitter to work for your small business! Download our small biz guide now: https://t.co/gdnMMYLI","date":"Tue Feb 26 08:37:11 GMT 2013","retweets":"22"}]
EDIT: As Alexander points out, you can just return the same object as you already do, but NOT use the $.each at all. My answer assumes you want to be able to pass back several objects and insert every one in a table row.

Related

Map json dynamically

I have a requirement to build a JSON dynamically and need to call an external API.
For instance,
Input : "FIRST_NAME": "XXX"
Based on the above input I need to build a JSON dynamically like below
{
"Req":{
"user":{
"CreatedTime":"2017-03-02T07:52:58Z",
"UpdatedTime":"2017-03-02T07:52:58Z",
"Details":{
"Names":[
{
"Name":{
"First":"kirtq"
}
}
]
}
}
}
}
If I get contact number as input : CONTACT_NUMBER:889999999
Then I have to build a JSON like below
{
"UpdateMemberReq": {
"Customer": {
"CreatedTime": "2017-03-02T07:52:58Z",
"UpdatedTime": "2017-03-02T07:52:58Z",
"CustomerDetails": {
"Contacts": {
"MobilePhone": {
"value": "07888728687"
}
}
}
}
}
}
Like this I have around 30 fields for each request I will get one filed based on that I have to build a JSON dynamically and once I prepared the JSON dynamically I have to call an external API (POST) by passing this JSON as raw type in the body.
I have implemented like below .
List list = new ArrayList();
Name user = mapper.readValue(json2, Name.class);
System.out.println(user);
Map<String, Object> name1 = new HashMap<>();
name1.put("Name", user);
list.add(name1);
Map<String, Object> map1 = new HashMap<>();
map1.put("Names", list);
Map<String, Object> map2 = new HashMap<>();
map2.put("CustomerDetails",map1);
Map<String,Object> map = new HashMap();
map.put("Customer",map2);
Can anyone suggest to me the best way to handle this in java/spring boot?
Thanks!!
Can anyone suggest to me the best way to handle this in java/spring boot?
Given that you don't have a fixed schema for which you want to create JSON, you'll have to do exactly like you do.
This means assembling a map dynamically and then mapping it to a json string.
What you can do to improve is try to extract common and reusable components, for building certain parts of the request.
I'd recommend you create a class structure to keep things manageable with some classes like ...
JsonGenerationService ( the main service the rest of the code uses )
UserJsonGenerator -> generates JSON for user entities
CustomerJsonGenerator -> generates JSON for customers
JsonGeneratorCommon -> contains all the common methods

Get Value from JSON String generated from C# WebService

This is my C# webservice which generates a JSON String. The below code block is what im using for that.
List<Dictionary<String, Object>> lstdict = new List<Dictionary<String, Object>>();
...
...
...
Logic for connecting db and getting records in msqldat (data reader)
goes here.
...
...
while (msqldat.Read())
{
var detls = new Dictionary<string, object>();
for (int i = 0; i < msqldat.FieldCount; i++)
{
detls.Add(msqldat.GetName(i), msqldat.IsDBNull(i) ? null :
msqldat.GetValue(i));
lstdict.Add(detls);
}
}
JavaScriptSerializer jss = new JavaScriptSerializer();
String mret = jss.Serialize(lstdict);
The above webservice is called in a java code from android studio and it returns the below String.
{"GetDataResult":"[
{\"uname\":\"hkIUZIikXVTC5aNaSva8IQ==\",
\"passwd\":\"hkIUZIikXVTC5aNaSva8IQ==\",
\"validupto\":\"\\\/Date(1545330600000)\\\/\",
\"dept\":\"juubHSHgLr\/3JWnrZCh5LeeW5Q7lioWOZ1\/Tg+YRy\/o=\",
\"rid\":1},
{\"uname\":\"hkIUZIikXVTC5aNaSva8IQ==\",
\"passwd\":\"hkIUZIikXVTC5aNaSva8IQ==\",
\"validupto\":\"\\\/Date(1545330600000)\\\/\",
\"dept\":\"juubHSHgLr\/3JWnrZCh5LeeW5Q7lioWOZ1\/Tg+YRy\/o=\",
\"rid\":2}]"}
I am trying to get the values in android application by using this Java code :
JSONObject uiobj = new JSONObject(mret);
JSONArray arrUserinfo = uiobj.getJSONArray("GetDataResult");
arrUserinfo.getJSONObject(0).getString("uname"))
The code fails at the second line. I'm new to JSON. Not sure if the JSON generated from c# code is not right or java code for parsing is not right. Please advise further. Thank you in advance.
The above json is serialized you need to parse json and then extract the object from it.
See this json valid..
{
"GetDataResult": [{
"uname": "hkIUZIikXVTC5aNaSva8IQ==",
"passwd": "hkIUZIikXVTC5aNaSva8IQ==",
"validupto": "/Date(1545330600000)/",
"dept": "juubHSHgLr/3JWnrZCh5LeeW5Q7lioWOZ1/Tg+YRy/o=",
"rid": 1
},
{
"uname": "hkIUZIikXVTC5aNaSva8IQ==",
"passwd": "hkIUZIikXVTC5aNaSva8IQ==",
"validupto": "/Date(1545330600000)/",
"dept": "juubHSHgLr/3JWnrZCh5LeeW5Q7lioWOZ1/Tg+YRy/o=",
"rid": 2
}
]
}
To parse json in java see below post..
https://www.geeksforgeeks.org/parse-json-java/

Html Slurping in Groovy

I am trying to parse HTML that comes to me as a giant String. When I get to Line 13, NodeChild page = it.parent()
I am able to find the key that I am looking for, but the data comes to me like This Is Value One In My KeyThis is Value Two in my KeyThis is Value Three In My Key and so on. I see a recurring trend where the seperator between the two is always UppercaseUppercase (withoutSpaces).
I would like to put it into an ArrayList one way or another. Is there a method that I am missing from the docs that is able to automatically do this? Is there a better way to parse this together?
class htmlParsingStuff{
private def slurper = new XmlSlurper(new Parser())
private void slurpItUp(String rawHTMLString){
ArrayList urlList = []
def htmlParser = slurper.parseText(rawHTMLString)
htmlParser.depthFirst().findAll() {
//Loop through all of the HTML Tags to get to the key that I am looking for
//EDIT: I see that I am able to iterate through the parent object, I just need a way to figure out how to get into that object
boolean trigger = it.text() == 'someKey'
if (trigger){
//I found the key that I am looking for
NodeChild page = it.parent()
page = page.replace('someKey', '')
LazyMap row = ["page": page, "type": "Some Type"]
urlList.add(row)
}
}
}
}
I can't provide you with working code since I don't know your specific html.
But: don't use XmlSlurper for parsing HTML, HTML is not well formed and therefor XmlSlurper is not the right tool for the job.
For HTML use a library like JSoup. You will find it much easier to use especially if you have some JQuery knowledge. Since you didn't post your HTML snippet I made up my own example:
#Grab(group='org.jsoup', module='jsoup', version='1.10.1')
import org.jsoup.Jsoup
def html = """
<html>
<body>
<table>
<tr><td>Key 1</td></tr>
<tr><td>Key 2</td></tr>
<tr><td>Key 3</td></tr>
<tr><td>Key 4</td></tr>
<tr><td>Key 5</td></tr>
</table>
</body>
</html>"""
def doc = Jsoup.parse(html)
def elements = doc.select('td')
def result = elements.collect {it.text()}
// contains ['Key 1', 'Key 2', 'Key 3', 'Key 4', 'Key 5']
To manipulate the document you would use
def doc = Jsoup.parse(html)
def elements = doc.select('td')
elements.each { oldElement ->
def newElement = new Element(Tag.valueOf('td'), '')
newElement.text('Another key')
oldElement.replaceWith(newElement)
}
println doc.outerHtml()

How do I pass a JSONObject to a Play Framework for Java template's javascript?

I am working with the Play framework (2.4) for Java. I want to pass a JSONObject to a javascript used inside one of the Play view templates.
On the Java side I prepare the JSONObject, like so:
(Keep in mind that this is a test vehicle.)
public static Result showBusinesses(){
List<Item> list = new ArrayList<Item>();
Item r = new Item();
r.id = "23234";
r.name = "Joes hardware";
Item s = new Item();
s.id = "23254";
s.name = "Martys collision";
list.add(r);
list.add(s);
return ok(views.html.wheel.render(getJSONObject(list)));
}
public static JSONObject getJSONObject(List<Item> list){
JSONObject jsonObject = new JSONObject();
try{
for (int i = 0; i < list.size(); i++) {
jsonObject.put(list.get(i).id, list.get(i).name);
}
}catch (JSONException e) {
}
return jsonObject;
}
In my Play template, I accept the JSONObject parameter:
#(item : org.json.JSONObject)
#import helper._
#import helper.twitterBootstrap._
#import play.api.libs.json.Json
...
So far, so good.
Until I attempt to use the object in my javascript:
If I place my object, #item, anywhere in the template besides inside the javascript, I get this:
{"23254":"Martys Pancakes","23234":"Joes place"};
which looks like a properly formed var to me.
I am inserting the JSONObject into the javascript like this:
<script type="text/javascript">
businesses = #item;
and I expect that to translate like this:
businesses = {
"23332" : "Joe's hardware",
"56755" : "Marty's collision"
};
And yet the object does not behave as expected. I suspect that I am not passing the parameter to the javascript in the correct way.
Can anyone enlighten me? Thanks.
I found the answer to my own question. It ended up being fairly simple. First of all, you don't need to mess with JSON. You pass a standard Java List to the Play template. Then you iterate through that list inside the Javascript variable curly braces. Here is the template code:
#(businesses: List[Business])
#import helper._
#import helper.twitterBootstrap._
...
<script type="text/javascript">
places = {
#for((item, index) <- businesses.zipWithIndex) {
#if(index != businesses.size-1) {
"#item.id" : "#Html(item.name)",}
else {"#item.id" : "#Html(item.name)"}
}
};
I used the built-in zipWithIndex because I needed commas separating every line but the last. The #Html() was needed to escape all the special chars that HTML needs to have translated. Once the javascript runs, you end up with your variable:
places = {
"345" : "Joe's Hardware",
"564" : "Jan's Party Store"
}

Pass data from Bean to javascript on jsf page. Google api directions

I need to pass waypoints to google maps javascript directions api from ManagedBean to jsf page.
I'm trying to make JSONArray and pass it to jsf:
private JSONArray routesJSON;
with getters and setters.
Than im creating JSON : in loop im adding Strings with LatLang of waypoints to List<String>
routes.add("new google.maps.LatLng(" + o.getLatitude() + "," + o.getLongitude()+")");
And im getting JSON :
[{"location":"new google.maps.LatLng(50.495121,22.1705)"},{"location":"new google.maps.LatLng(50.57082,22.06813)"},{"location":"new google.maps.LatLng(50.570549,22.047871)"},{"location":"new google.maps.LatLng(50.521389,21.912695)"},{"location":"new google.maps.LatLng(50.495121,22.1705)"}]
from:
for()
array.put(obj);
}
System.out.println(array);
in JSF function for displaying route : (it works with hardcoded data)
function calcRoute() {
var waypts = [];
var start = new google.maps.LatLng(#{someBean.startLatitude}, #{someBean.startLongitude});
var end = new google.maps.LatLng(49.712112, 21.50667);
var way = #{someBean.routesJSON};
var request = {
origin:start,
destination:end,
optimizeWaypoints: true,
waypoints:way;
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
But when im displaying that page map doesnt appear. I know it's probably because of " in JSON but i dont know how to remove it. Or may there are easiest ways to pass waypoint data from Bean to jsf page?
Instead of returning a JSON data packet that contains javascript statements like "new google.maps.LatLng(50.495121,22.1705)", it's more sensible to return just the coordinates.
So if you had a JSON packet that looks like this in your javascript (I don't know how to pass data between your Java and Javascript):
var routes = [
{"lat":"50.495121", "lng":"22.1705"},
{"lat":"50.57082", "lng":"22.06813"},
{"lat":"50.570549", "lng":"22.047871"},
{"lat":"50.521389", "lng":"21.912695"},
{"lat":"50.495121", "lng":"22.1705"}
]
You can turn this into an array like so:
var way = [];
for (var i = 0; i < routes.length; i++) {
way.push(new google.maps.LatLng(parseFloat(routes[i].lat), parseFloat(routes[i].lng)));
}
NB: the use of parseFloat to convert strings like "50.495121" into floating point numbers.

Categories