How to create JSON array in java with non-string key names? - java

I am using this bootstrap transfer plugin at UI which i have to populate with the help of data sent from java application. This plugin requires the data to be an array of objects with 'value' and 'content' properties.
I can easily create a list in java and convert it to JSON array, but the problem here is that this plugin requires key names as non string names. I tried using string key names but that just didn't worked. I looked up for ways to create non-string key names in JSON and the only way i could find was to write my own parser, and that was also not recommended. So how can i prepare my data in java for this plugin ??
Edit:
As mentioned in the plugin documentation, here is a sample data to populate it.
$(function() {
...
var t = $('#test').bootstrapTransfer();
t.populate([
{value:"1", content:"Apple"},
{value:"2", content:"Orange"},
{value:"3", content:"Banana"},
{value:"4", content:"Peach"},
{value:"5", content:"Grapes"}
]);
...
});
When i prepare a JSON array, it is like {"value":"1", "content":"Apple"} which doesn't work for this plugin.

You might check how it runs again when you use a quoted string. When accessing a JSON object, the quotes for keys are not needed. Take for example this code (in Nodejs):
var console = require("console");
var data = { "value1" : 13,
"value2" : "hello",
value3: 15,
value4 : "hello again" };
console.log("Value 1 = " + data.value1 );
console.log("Value 2 = " + data.value2 );
console.log("Value 3 = " + data.value3 );
console.log("Value 4 = " + data.value4 );
Some of the object is declared with quoted strings, and some are not. All are accessed without the quotes, and my console shows:
Value 1 = 13
Value 2 = hello
Value 3 = 15
Value 4 = hello again
So it really shouldn't matter how your keys are defined in java. I know that isn't an exact answer to your question of how to do it, but you really shouldn't need to.

Related

How can I set a literal JSON value in AWS CDK with Java?

I have to set a literal JSON value to define the home directory mapping of a user in Java based CDK definition:
CfnUser user1 = CfnUser.Builder.create(this, "user1 ")
.userName("user1")
.serverId(transferServer.getAttrServerId())
.homeDirectoryType("PATH")
.homeDirectory("/path/to/home")
.homeDirectoryMappings(List.of("Entry:/", "Target:/path/to/home"))
.role(role.getRoleArn())
.build();
The above code fails, because the List passed to homeDirectoryMappings() is not a software.amazon.awscdk.IResolvable. Somehow I have to create a IResolvable which represents this JSON:
[
{
"Entry":"/",
"Target":"/bucket3/customized-reports/"
}
]
I searched throuth the implementations of IResolvable but cannot find a suitable class.
So how can I pass a JSON literal to a method that takes a IResolvable?
After reading the error message one more time I noticed, that the homeDirectoryMappings() method accepts a List of HomeDirectoryMapEntryProperty instances. So there's actually no need for a IResolvable.
So the correct code lookes like this:
CfnUser user1 = CfnUser.Builder.create(this, "user1 ")
.userName("user1 ")
.serverId(transferServer.getAttrServerId())
.homeDirectoryType("LOGICAL")
.homeDirectoryMappings(List.of(new HomeDirectoryMapEntryProperty.Builder()
.entry("/")
.target("/s3-bucket/home/${transfer:UserName}")
.build())
)
.role(dlRole.getRoleArn())
.build();

Android app and Database Communication: JSON Parsing and List View

I am developing an app that communicates with Database, to retrieve values. I am using PHP for the Backend, and developing on Android Studio, using the Volley Library.
My problem is, the values that I need to send are multiple records of a table, each with four columns, for example name, age, department, and country. I am using JSON to encode these values, but I need help with how to proceed. Should I use JSON encoded 2D Arrays? if so, how to make use PHP to construct this array, as there can be variable numbers of rows.
Also, How to parse that JSON Object/Array in Android (Java)?
As of now, this is my progress:
JSON Output in browser:
{"name0":"ABC","age0":"25","department0":"Medical","country0":"XYZ","name1":"DEF","age1":"26","department1":"Engg.","country1":"XYZ"}
Here, I named each "key" of JSON using a Loop in PHP, and encoded as JSON Object. But Having Difficulty in displaying this in Android. I have used a XML layout with 4 textviews, and LISTVIEW in the main Activity XML File.
I would suggest a different json structure for encoding. Yours will get messy pretty quick if there are a lot of records. For example you would have name0, name1, ... nameN. It would be better to make an array like so:
[
{
"name" : "ABC",
"age" : 25,
"department" : "Medical",
"country" : "XYZ"
},
{
...
}
]
Notice that there are no indices concatenated to your keys. You can get the index based on the json object node's position in the array if you need it.
As for parsing it in Android, you can refer to the documentation. There is a Json parser that comes with the SDK so all you need to do is read in your string as a json array and iterate over its object nodes as needed.
For example
String jsonResponse = " ... "; // whatever the php backend gives you when you make a call to the endpoint
JSONArray arr = new JSONArray(jsonResponse);
for (int i=0; i<arr.length(); i++) {
JSONObject obj = arr.get(i);
String name = obj.getString("name");
...
}

How to use JsonIter to get a specific key value from json , by using any getter method if available ?

Am using http://jsoniter.com/ java lib to parse json , it seems with this lib , it only possible to iterate over through the JSON and did not provide any api to get value for specific key like we have in org.json like below
jsonObject.get("some_key")
so do we have such type of getter methods in http://jsoniter.com/ also , can any one please help me in that .
This is probably already too late, but you can do it like this:
String jsonString = "{'a':1,'b':'text'}".replaceAll("'", "\"");
Any jsonObject = JsonIterator.deserialize(jsonString);
long number = jsonObject.get("a").toLong();
String text = jsonObject.get("b").toString();

Creating a dynamic query with MongoDB, Java and Jongo

I'm using a combination of Java, the Play Framework using Java and not Scala, MongoDB and Jongo as my go between for a basic web CRUD app. I keep receiving a JSON parse exception even though my string doesn't contain any illegal characters. It's actually failing on closing curly bracket at the end of the statement. Below is my error and code. The query string is just a string builder, searching if an object is empty or has a value, if it has a value it's appended to a string.
Jongo method:
public static Iterable<OneDomain> findWithQueryString(String queryString){
return domains().find("{#}", queryString).as(OneDomain.class);
}
Controller Methods:
String builder example:
if(queryStringBuilder.toString().equalsIgnoreCase("")){
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}else{
queryStringBuilder.append(" , ");
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}
String queryString = queryStringBuilder.toString();
Iterable<OneDomain> filteredIterable = OneDomain.findWithQueryString(queryString);
Gives me this error:
Caused by: com.mongodb.util.JSONParseException:
{"source : Online Lists , blacklist : true , vetted : true , is : false , isNot : true"}
^
with the error on the "}" ending it.
In addition to that, if I try to escape the characters by putting in a \" so it becomes \"date\" it will parse and error out like so:
Caused by: com.mongodb.util.JSONParseException:
{"\"source\" : \"Online Lists\" , \"blacklist\" : true , \"vetted\" : true , \"is\" : false , \"isNot\" : true"}
Can I actually do this or because it's Java being inserted into it, the quotes will be around the whole string and thus it's trying to read it as a single JSON field vs it being the whole query?
First, make sure not to make your self vulnerable to injection attacks. Read up on injection attacks in general, and more specifically on MongoDB, eg OWASP page on Testing for NoSQL injection.
While you can indeed pass a generated query string into the find method I would not advise it. I did the same and had big problem when we generated a query containing the jongo substitution parameter #, ie
// This will throw an exception:
// java.lang.IllegalArgumentException: Not enough parameters passed to query: {"value":"#"}
...find("{" + "\"value\":\"#\"" + "}")
My solution is to pass a DBObject:
import com.mongodb.BasicDBObject
...find("#", new BasicDBObject().append("value", "#"))
It can also be built with the QueryBuilder:
import com.mongodb.QueryBuilder
...find("#", QueryBuilder.start("value").is("#").get())
It would be nice though to have query builder support directly in the Jongo API: https://github.com/bguerout/jongo/issues/173
Found the answer. Need to drop the substitution and instead my method looks like
domains().find("{"+queryString+"}").as(OneDomain.class);

Faceting using SolrJ and Solr4

I've gone through the related questions on this site but haven't found a relevant solution.
When querying my Solr4 index using an HTTP request of the form
&facet=true&facet.field=country
The response contains all the different countries along with counts per country.
How can I get this information using SolrJ?
I have tried the following but it only returns total counts across all countries, not per country:
solrQuery.setFacet(true);
solrQuery.addFacetField("country");
The following does seem to work, but I do not want to have to explicitly set all the groupings beforehand:
solrQuery.addFacetQuery("country:usa");
solrQuery.addFacetQuery("country:canada");
Secondly, I'm not sure how to extract the facet data from the QueryResponse object.
So two questions:
1) Using SolrJ how can I facet on a field and return the groupings without explicitly specifying the groups?
2) Using SolrJ how can I extract the facet data from the QueryResponse object?
Thanks.
Update:
I also tried something similar to Sergey's response (below).
List<FacetField> ffList = resp.getFacetFields();
log.info("size of ffList:" + ffList.size());
for(FacetField ff : ffList){
String ffname = ff.getName();
int ffcount = ff.getValueCount();
log.info("ffname:" + ffname + "|ffcount:" + ffcount);
}
The above code shows ffList with size=1 and the loop goes through 1 iteration. In the output ffname="country" and ffcount is the total number of rows that match the original query.
There is no per-country breakdown here.
I should mention that on the same solrQuery object I am also calling addField and addFilterQuery. Not sure if this impacts faceting:
solrQuery.addField("user-name");
solrQuery.addField("user-bio");
solrQuery.addField("country");
solrQuery.addFilterQuery("user-bio:" + "(Apple OR Google OR Facebook)");
Update 2:
I think I got it, again based on what Sergey said below. I extracted the List object using FacetField.getValues().
List<FacetField> fflist = resp.getFacetFields();
for(FacetField ff : fflist){
String ffname = ff.getName();
int ffcount = ff.getValueCount();
List<Count> counts = ff.getValues();
for(Count c : counts){
String facetLabel = c.getName();
long facetCount = c.getCount();
}
}
In the above code the label variable matches each facet group and count is the corresponding count for that grouping.
Actually you need only to set facet field and facet will be activated (check SolrJ source code):
solrQuery.addFacetField("country");
Where did you look for facet information? It must be in QueryResponse.getFacetFields (getValues.getCount)
In the solr Response you should use QueryResponse.getFacetFields() to get List of FacetFields among which figure "country". so "country" is idenditfied by QueryResponse.getFacetFields().get(0)
you iterate then over it to get List of Count objects using
QueryResponse.getFacetFields().get(0).getValues().get(i)
and get value name of facet using QueryResponse.getFacetFields().get(0).getValues().get(i).getName()
and the corresponding weight using
QueryResponse.getFacetFields().get(0).getValues().get(i).getCount()

Categories