Reputation: 933
I would like to read in the string {"a": 1.0}
as a generic Java Object while 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}
? Note that, I have to read it in as an Object
(due to other program constraints).
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());
}
}
}
Upvotes: 7
Views: 15540
Reputation: 3234
The created object will be a map (like the other comments) and so its toString
produces what you're seeing, {a = 1}
. To get your code to print something closer to your input value, you need to use Jackson to write it back out with something like:
System.out.println(mapper.writeValueAsString(myObject));
That gives me what I believe you're looking for:
{"a":1.0}
In other words, Jackson has deserialized your input string into an arbitrary Java object. When you call toString
on the object, its own toString
is, of course, used. This can write the object however it pleases, including using the method from Object
. To reproduce the input string, you have to use Jackson to serialize our object back out.
Upvotes: 7
Reputation: 116472
When Jackson is told to bind JSON into Object.class, it does just that; but since it has no a priori knowledge of what might be in that JSON (or what classes one might want to use), it has to use most basic Java types: Maps, Lists, Numbers, Booleans and Strings. So any JSON Object is represented by Map; JSON Array by List, and so on.
If you want a custom object, you must specify its type; or, when serializing, enable inclusion of explicit type information ("polymorphic type handling"). This will add either class name, or type name, and can be used to deserialize back to exact type.
To do this, either type itself (or one of its supertypes) must use @JsonTypeInfo annotation; or, if it is an Object property, @JsonTypeInfo for property (field or method).
Upvotes: 2
Reputation: 298818
If you use a debugger, you will see that the type of the returned Object is LinkedHashMap
. So what you see is the output of LinkedHashMap.toString()
. There's no way for Jackson to change that, so you can either cast it to a Map and create the String yourself or ask for another return type that generates the 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'
}
Upvotes: 2
Reputation: 597016
You need an existing class that matches the desired json structure. Object is not such class. You can still refer to it as Object
, if that's needed:
Object myObject = mapper.readValue("{\"a\": 1.0}", SomeClass.class);
Upvotes: 3