Map inside a Map with Jackson with JSF - java

I'm using Jackson to read/write datas from/into json files and I have an issue with the User POJO. It has a Map wich is supposed to be the ways to contact the User (so it can have from 0 to 7, depending on the Enum). I want to be able to put ways to contact using a form in JSF.
I tried something like value="#{config.user.contacts[EMAIL_PRO]}"
where of course EMAIL_PRO is an Enum (later, the user should be able to chose the Enum himself, but right now I try simple).
But when I do so, the error is
Null key for a Map not allowed in JSON
wich I understand, 'cause my debug says that the value returned is{null = null}. Now first question : since the map is empty, is JSF supposed to work simply like that ? The key "EMAIL_PRO" doesnt exists yet, but shouldn't JSF make the work done for me, and put right value with the key ?
The other question is much more about Jackson and Maps. As I said, my POJO User contains a Map, and the json file is a Map himself (containing multiple users).
Is it really possible to write a Map into this file using Jackson where the Map is Map<String, Object> and the Object contains a Map<Enum, Object> ? And if yes, how ?
Thanks for the help
PS: I cannot change either my APIs or my POJOs.

I think this is a repeated post, see How to convert hashmap to JSON object in Java
And as it says on one of the responses:
Map<String, Object> data = new HashMap<String, Object>();
data.put( "name", "Mars" );
data.put( "age", 32 );
data.put( "city", "NY" );
JSONObject json = new JSONObject();
json.putAll( data );
System.out.printf( "JSON: %s", json.toString(2) );
output:
JSON: {
"age": 32,
"name": "Mars",
"city": "NY"
}
You can also try to use Google's GSON.Google's GSON is the best library available to convert Java Objects into their JSON representation

Related

Serialize a hashmap to a json in a certain feilds in JAVA

I need to serialize a map to a json in a certain order.
This is the map
HashMap<String, String> dataMap = {
"CompanyCode": "4",
"EntyyCode": "2002296",
"SubEntityCode": "000",
"ContractNumber": "52504467115",
"Progressive Contract": "0",
"DocumentNumber": "200003333494028",
"LogonUserName": "AR333",
"Progressive Title": "0"
}
This is the json model I would like:
{
"Policy": {
"ContractNumber": "52504467115",
"ProgressiveContract": "0"
},
"Title": {
"LogonUserName": "AR333",
"ProgressiveTitle": "0"
},
"BusinessChannel": {
"CompanyCode": "4",
"EntyyCode": "2002296",
"SubEntityCode": "000"
},
"Document": {
"DocumentNumber": "200003333494028"
}
}
I need to convert this map into a JSON string. I know that this can be done using Jackson as below:
new ObjectMapper().writeValueAsString(map);
How do I do this using Jackson? Or is there any other way to do this in Java?
Thank you
First of all, the solution you request contains a second problem: partition. Not only must the items contain a particular order, but they must also somehow be divided over different categories. In Java, these categories usually correspond to their own classes or, since recently, records. Then the top level class (corresponding to the unnamed outer object of the JSON) determines ordering, as so (the name Contract is my choice):
record Contract(
Policy policy,
Title title,
BusinessChannel businessChannel,
Document document )
{
}
with each of the properties of Contract having their own class, e.g.:
record Policy( String contractNumber, int progressiveContract )
etc.
Serializing Contract then recursively serializes each of its parameters, with the required outcome as the result.
This would be the 'standard' way.
So, since you start with a HashMap, which by contract offers no guarantee of ordering, let alone an easy way to partition its contents into sub-objects, you could try two things:
Rethink the use of a map. Switching to the class structure takes care of the structure automatically.
Manually stream and convert the values in order (or use e.g. a TreeMap with custom Comparator) and then partition the values themselves. This probably requires more work than a map saves.

Validate facts having nested maps using drools

I have a class Fact which is a extends java.util.HashMap class. I am passing object of this class as fact to drools.
Now an instance of fact looks like this (Map<String, Object>):
{
"key1": "value"
"attributes": [{"name": "name1", "value": "value1"},{"name": "name2", "value": "value2"},{"name": "name3", "value": "value3"}...]
"locks": [{"type": "type1", "value": "value1", "attributes": {"key_a1": "val_a1""key_a2": "val_a2"...}}]
}
Running validations on root level entries in this map is straight forward e.g. running validations on key1.
Now, I want to run some validations on attributes and locks.
For attributes, I want to ensure that all attributes which are needed are present in this map and their corresponding values are correct. So I do this in the when block:
fact: Fact(this["key1"] != null && this.containsKey("attributes"));
attributesEntries: Entry(key == "attributes") from fact.entrySet();
attributesMaps: LinkedHashMap() from attributesEntries;
fact is HashMap
attributes are of type ArrayList<LinkedHashMap<String, String>> (an id key is also added for the LinkedHashMap whose value is the value of key name only).
locks are of type ArrayList<LinkedHashMap<String, Object>>
locks have attributes of type Map<String, String>
but it is not working. When I evaluate attributesEntries it is ArrayList<LinkedHashMap> and it has all the expected values but attributesMaps comes as empty. I also tried passing filters like LinkedHashMap(key == 'key1', value == 'val1') but that also didn't work. Tried looking for solutions and none were available for this sort of structure. Whatever was available I tried to extend but didn't work.
Is this possible to achieve and if so how? Also, how do I validate value (not empty and matches a pattern) once I am able to get it from the Map.
I am new to drools and we are using 5.4.0.Final version of drools.
Also, how can I work with the next level nested Map in locks.
I once had the misfortune of working on a project where we made this same mistake and had our class extend HashMap. (Fair warning: HashMap doesn't serialize well so you're going to use a lot of extra memory.)
I'm going to assume several things about your model because you neglected to share the class definition itself.
But I'm going to assume the following, based on your example JSON:
You have added a string value ("value") with the key "key1"
You have added a List<Map<String, ?>> value (possibly a List<Fact>) with the key "locks"
You have added a List<Map<String, ?>> value (possibly a List<Fact>) with the key "attributes"
The HashMap's get(key) method will return an object value; you've already noted the special this[ key ] syntax.
From your partial rule attempt, it's not entirely clear what you're trying to do. I think you're trying to get the List<Map<String, ?>> that is saved in your map under the "attributes" key.
rule "Do something with the attributes"
when
$fact: Fact( this["key1"] != null,
$attr: this["attributes"] != null )
then
System.out.println("Found " + $attr.size() + " attributes");
end
this["attributes"] returns the value associated with the key attributes. In this case, it's a List or whatever you shoved in there. If the key doesn't exist, the null check handles that.
You also asked how you could do stuff with a child map inside one of those lists. Let's say that want to do something with the attribute that has "name": "name1" ...
rule "Do something with the 'name = name1' attribute"
when
$fact: Fact( this["key1"] != null,
$attributes: this["attributes"] != null )
$nameAttr: Map( this["name"] == "name1" ) from $attributes
then
// do something with $nameAttr
end
The pattern repeats, of course. Let's say you've shoved yet another List<Map<String, ?>> into your attribute maps:
rule "Do something with a child of 'name' attribute"
when
$fact: Fact( this["key1"] != null,
$attributes: this["attributes"] != null )
$nameAttr: Map( this["name"] == "name1",
$attrKids: this["children"] != null ) from $attributes
$childNameAttr: Map( this["name"] == "child1" ) from $attrKids
then
// etc.
end
I strongly recommend reconsidering your object model to not be Map-based. At the company I worked at where all of our projects were built against a nested Map-based model and running Drools 5.0.1, I spent significant time and effort upgrading parts of it to Drools 7 and a proper model that passed in just the data we needed. It saved a ton of resources and ended up being much faster.

How to convert Map created from JSON to another Map in Java?

I got JSON file like this:
{
"issues": [
{
"no1": 5509,
"date": 1451520000
},
{
"no1": 6713,
"date": 1451433600
}],
"no2": [
220380,
163950,
213330,
215250,
174300]
}
I need to create a map issues where the no1 value will be key of the map and date value will be a value of the map. I've got already method which transfers JSON to map from file, and I know how to get the issues which will be: mapFromJson.get("issues"); what I get is:
issues=[{ no1: 5509.0, date: 1.45152E9}, {no1: 6713.0, date: 1.4514336E9}]
How to convert this to map?
You can convert to JSON using JSON Library (you must to attach JAR file in your project). Also, I found a good answer for convert JSON to Map in this link. I recommended to use these functions.
Example:
JSONObject json = new JSONObject(<your_json_string>);
ArrayList issues = (ArrayList) jsonToMap(json).get("issues");
Each element in the ArrayList issues, it's already HashMap. For example, if you want to get date of no1, you could access of this way:
((HashMap)issues.get(0)).get("date")

How to make a JsonObject in a ordered way?

I want to create a JSonObject with some values for call a webservice but where webservice in a order like:
{
"id" : 1
"email" : "test#test.com",
"pin" : 1234,
"age" : 25,
"firstName" : "Test First Name",
"lastName" : "Test Last Name",
"location" : "India",
"phone" : "1234567890"
}
but when I create a json object from android code it is not maintaining the order like:
requestJOB=new JSONObject();
requestJOB.put("userid",Pref.getValue(this, Const.USER_ID, requestJOB.optString("userid")));
requestJOB.put("email", Pref.getValue(this, Const.PREF_EMAIL, requestJOB.optString("email")));
requestJOB.put("pin", Pref.getValue(this, Const.PREF_PIN, requestJOB.optString("pin")));
requestJOB.put("age", Pref.getValue(this, Const.PREF_AGE, requestJOB.optString("age")));
requestJOB.put("firstname", etFirstName.getText().toString().trim());
requestJOB.put("lastname", etLastName.getText().toString().trim());
requestJOB.put("phone", etPhone.getText().toString().trim());
requestJOB.put("location", etLocation.getText().toString().trim());
I write the code my desired order but JsonObject change the order in run time. I also tried with map and LinkedList but A exception is
occured when I want to convert LIST to JsonObject.
I searched in stackoverflow where no satisfactory answer.
In this situation I don't understand exactly what I have to do.
In Android platform there is better way to serialize a object in json by using Google GSON API... Which provide all possible functionality to convert a class to their corresponding JSON. U can prepare nested jsonobject ..
Nested like json object with in a json object. Json array embedded within a json. Object
Multiple jsonarray with in a same json object. And their may be multiple variety .. Just explore this jar .. It's very easy to use and user-friendly jar. Just go and grab it .. Hopefully u feel better with this API
I used this jar in my Android project actually

Do JSON keys need to be unique? [duplicate]

This question already has answers here:
Does JSON syntax allow duplicate keys in an object?
(12 answers)
Closed 6 years ago.
The following question is related to a question that I had asked earlier: Help parsing simple JSON (using JSON for JAVA ME)
Do JSON keys need to be unique? For example, I was having trouble parsing the following XML (with JSON ME):
{
"name" : "JACK",
"name" : "JILL",
"name" : "JOHN",
"name" : "JENNY",
"name" : "JAMES",
"name" : "JIM"
}
And, apparently, its because the keys must be unique. I'm just wondering if thats true in all cases or not. For example, if I were using something other than JSON ME, would I be able to parse all of these names?
Thanks.
There is no "error" if you use more than one key with the same name, but in JSON, the last key with the same name is the one that is going to be used.
In your case, the key "name" would be better to contain an array as it's value, instead of having a number of keys "name". It doesn't make much sense the same object or "thing" to have two names, or two of the same properties that are in conflict.
E.g.:
{
"name" : [ "JOHN", "JACK", "...", ... ]
}
From RFC 4627:
An object structure is represented as a pair of curly brackets
surrounding zero or more name/value pairs (or members). A name is a
string. A single colon comes after each name, separating the name
from the value. A single comma separates a value from a following
name. The names within an object SHOULD be unique.
jQuery is able to parse it. But if you try to access it, it's just giving back the last value.
Check out
http://jsfiddle.net/MQmM4/2/
So, it's parsable, I guess, but the value gets overridden if you use the same key.
here is a possible solution using array. just use array index
the_json_array.getJSONObject(0);
{"nameList":
[{"name" : "JACK"},
{"name" : "JILL"},
{"name" : "JOHN"},
{"name" : "JENNY"},
{"name" : "JAMES"},
{"name" : "JIM"}]}
A JSON Object looks like the following
public JSONObject(Map<?, ?> map) {
this.map = new HashMap<String, Object>();
if (map != null) {
for (final Entry<?, ?> e : map.entrySet()) {
final Object value = e.getValue();
if (value != null) {
this.map.put(String.valueOf(e.getKey()), wrap(value));
}
}
}
}
A JSON Object is basically a hashmap containing key value pair.
This is why you are getting overwritten each time. To avoid this
Either you must have unique key values
Or you should wrap the key value pair as individual objects into an array
Have a look at this JSON Object java implementation to know in depth about JSON.

Categories