Using Struts 2 builtin JSON utility class - java

In an Struts 2 project, we need to serialize and deserialize objects, as our requirement is very simple, we decide to use Struts 2 JSONUtil instead of gson.
import org.apache.struts2.json;
String json = JSONUtil.serialize(myAccountVO);
// return: {"accountNumber":"0105069413007","amount":"1500","balance":"215000"}
For deserialization, we face the class cast exception
AccountVO vo =(AccountVO) JSONUtil.deserialize(json);
//Exception
I find that the deserialization returns a map with key value of object properties. So I must do as:
HashMap<String,String> map = (HashMap) JSONUtil.deserialize(string)
accountVo.setAccountNumber(map.get("accountNumber"));
....
Well can I do it better or I am expecting too much from this utility.

After you have deserialized JSON, you can use JSONPopulator to populate bean properties from a map. E.g.
JSONPopulator populator = new JSONPopulator();
AccountVO vo = new AccountVO();
populator.populateObject(vo, map);

Related

How to jsonify a object with new values?

I have some object with different atributes' types: String,Float,LocalDate and so on. To turn this object into a json String, I use (com.google.gson.Gson)
gson.toJson(object);
But now I want to add a String to it:
{
"warning" : "old",
--Jsonified Object--
}
How can I add specific key-values data into a object without doing boilerplate code or creating a new object that has a new attribute plus the old ones?
You can use com.google.gson.JsonObject class to add extra fields.
JsonObject jsonObject = (JsonObject)gson.toJsonTree(object, YourObjects.class);
jsonObject.addProperty("warning" , "old"); // add required extra fields
String json = gson.toJson(jsonObject); // create son string
The easiest way to do this without creating a new class or modify the current is to work with maps. Of course it still needs some boilerplate, but you can create a method where you do all this.
With Gson starting from the already generated json you can create a map, modify this map and then create the json again.
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
// here you process the map, e.g. put or remove keys
map.put("warning", "old");
String json = gson.toJson(myMap);
If you do not want to start from the created JSON I recomend to transform your object in a map with jackson object mapper and then process the map and create the json. You should use another library like jackson because Gson does not provice a way to transform a object to a map.

Convert Json to a java object

What is the way to generate a Java object with get and set methods?
You should write a java bean with properties maching the JSON key's, from that point since you already have a reader its a simple as
YourObject obj = gson.fromJson(br, YourObject.class);
UPDATE
With respect to your comment, when you don't want or can't create a bean it usually boils down to parsing JSON to map. GSON (afaik) doesn't have a built-in for this, but its not hard to build a method that will traverse GSON's objects. You have an example in this blog
http://itsmyviewofthings.blogspot.it/2013/04/jsonconverter-code-that-converts-json.html
As you seem to be open to alternatives, take a look at Jackson as well (the two libs are the de-facto standard in JAVA).
With jackson you don't have to create a bean to support deserialization, e.g.
String json = "{\"id\":\"masterslave\"}";
Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();
//convert JSON string to Map
map = mapper.readValue(json,
new TypeReference<HashMap<String,String>>(){});
http://www.jsonschema2pojo.org/
That link helps generate the Java object format based on the GSON you feed in. Just make sure you set the settings exactly as you need it. As always, it's not a good idea to just copy-paste generated code, but it might be of help.

Serialization and Deserialization of generic Map for Java and external use

I have a Map<String, Object> which I am using as a mapping for a JSON document, however want to create and maintain Java type information at the same time as retaining the structure of the document.
I'm attempting to use Jackson to create the document and it seems to work fine but I'm seeing something strange when attempting to deserialize it. A very simple serialization example:
final ObjectMapper mapper = new ObjectMapper().enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, JsonTypeInfo.As.EXTERNAL_PROPERTY);
final Map<String, Object> map = Maps.newHashMap();
map.put("test", new Date());
final String ser = mapper.writeValueAsString(map);
final Map<String, Object> deser = mapper.readValue(ser, new TypeReference<HashMap<String, Object>>(){});
System.err.println(deser.get("test").getClass());
Gives the serialized form {"test":1410721662084,"#class":"java.util.Date"} which seems fine but when deserializing returns the type of "test" to be Long.
If I change the type serialization to use WRAPPER_ARRAY rather than EXTERNAL_PROPERTY then the type of "test" is correctly returned as Date, but doing this alters the structure of the JSON document so is not something I'm allowed to do. How do I retain the structure of the document as well as allow deserialization back to the correct types?
This is against Jackson 2.4.2.
Deserialization with maps is always tricky as maps don't preserve type information, which makes Jackson resort to #class and that not something you usually want. Instead, you can create a simple class:
public class TestClass {
private Date test;
//getters and setters omitted
}
This class has concrete structure and JSON will serialize it as
{ "test" : 1410721662084}
which is much cleaner and type-safe representation of your object. Then you just need to pass TestClass.class to readValue() method and your test attribute will be magically converted to proper type (Date)

Javascript Object to Java List

I have the following type of JSON I want to send to Java (I'm using Jersey and the default JSON Parser it comes with)
{ "something" : "1", "someOtherThing" : "2" , ... }
But instead of creating an Object with all these properties in Java, I would like to have a Single HashMap (or whatever) that will allow me to still have access to the Key and the Value
Is such a thing possible?
I don't really have any code that does the transformation, I use Jersey like this
#POST
#Path("/purchase")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public StatusResult purchase(UserPurchaseRequest upr) {
}
If i put properties something and someOtherThing as Strings in my UserPurchaseRequest object, everything will come in fine, but I want to have everything in one structure (because I don't know how many values I will get, and I need their names as well)
Yes, it is possible. But still, it depends on what JSON java API you are using. For example using Jackson JSON you can create HashMap json string like this
ObjectMapper obj = new ObjectMapper();
String json = pbj.writeValue(<HashMap object>);
or vice-versa
HashMap obj = obj.readValue(json, HashMap.class);
Note - org.codehaus.jackson.map.ObjectMapper
You just need to add a Property to your Object like this
private HashMap<String,String> purchaseValues;
Jersey takes care of the rest, for some reason while you are debugging, most of the entries appear as null in the HashMap

Json, Jackson and serialization

I've started to using Json with Jackson library and i found little problem.
I'm creating Json object:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> userInMap = new HashMap<String, Object>();
then i'm adding fields:
userInMap.put("user", "active");
userInMap.put("uuid", uuid);
And after all when im trying to output this object i have Json object but without ", i mean i supposed to have:
{"user":"active", "uuid":"lasdnfa"}
but i have:
{user:active, uuid:lasdnfa}
and another thing - i want to add this object to memcache, but before i do this, i have to serialize this object. How i can serialize Json object?
Thanks
If you are using toString() on your object, you might need your mapper to output the value this way :
System.out.println(mapper.writeValueAsString(userInMap)));

Categories