Generic serialization of objects in Jackson with Java

I would like to read the string {"a": 1.0} as a generic Java object, keeping the same string format. However, when I try, Jackson automatically changes the internal representation to {a = 1} . In other words, how can I get the following code to print {"a": 1.0} instead of {a = 1} ? Please note: I have to read it as an Object (due to other program limitations).

 import org.codehaus.jackson.map.ObjectMapper; public class Main { public static void main(String[] args) { try { ObjectMapper mapper = new ObjectMapper(); Object myObject = mapper.readValue("{\"a\": 1.0}", Object.class); System.out.println(myObject.toString()); } catch (Exception e) { e.printStackTrace(); System.err.println(e.getMessage()); } } } 
+7
source share
4 answers

The created object will be a map (like other comments), and therefore its toString creates what you see, {a = 1} . To get your code to print something closer to your input value, you need to use Jackson to write it with something like:

 System.out.println(mapper.writeValueAsString(myObject)); 

This gives me what I believe you are looking for:

 {"a":1.0} 

In other words, Jackson deserialized your input string into an arbitrary Java object. When you call toString on an object, its own toString , of course, is used. It can write an object, but I like it, including using the method from Object . To play the input string, you must use Jackson to serialize our object.

+7
source

You need an existing class that matches the desired json structure. The object is not such a class. You can still reference it as an Object if necessary:

 Object myObject = mapper.readValue("{\"a\": 1.0}", SomeClass.class); 
+3
source

If you use a debugger, you will see that the return type is LinkedHashMap . So you see the result of LinkedHashMap.toString() . For Jackson, this is impossible, so you can either drop it on the map, create a String yourself, or set a different return type that generates a JSON string for you:

 if(myObject instanceof Map<?, ?>){ final Map<?, ?> map = (Map<?, ?>) myObject; final StringBuilder sb = new StringBuilder("{"); boolean first = true; for(final Entry<?, ?> entry : map.entrySet()){ if(first){ first = false; } else{ sb.append(","); } sb.append("\n\t'") .append(entry.getKey()) .append("':'") .append(entry.getValue()) .append("'"); } if(!first){ sb.append("\n"); } sb.append("}"); System.out.println(sb.toString()); } else{ System.out.println(myObject); } 

Output:

 { 'a':'1.0' } 
+2
source

When Jackson is ordered to associate JSON with Object.class, he does just that; but since he does not have a priori knowledge of what can be in this JSON (or which classes can be used), he should use most of the basic Java types: Maps, Lists, Numbers, Booleans and Strings. Thus, any JSON object is represented by a Map; JSON Array by List etc.

If you need a custom object, you must specify its type; or, during serialization, enable the inclusion of explicit type information ("polymorphic type processing"). This will add the class name or type name and can be used to deserialize back to the exact type.

To do this, either the type itself or one of its supertypes must use the @JsonTypeInfo annotation; or, if it is an Object property, @JsonTypeInfo for the property (field or method).

+2
source

All Articles