Reputation: 532
I have an Entity class below with two String fields: name and description. The description field is to contain a raw JSON value e.g. { "abc": 123 }
@Getter
@Setter
public class Entity {
private String name;
@JsonRawValue
private String descriptionJson;
}
I've got simple test code below using Jackson to serialize and deserialize:
Entity ent = new Entity();
ent.setName("MyName");
ent.setDescriptionJson("{ \"abc\": 123 }");
// Convert Object to JSON string
String json = mapper.writeValueAsString(ent);
// Convert JSON string back to object
Entity ent2 = mapper.readValue(json, Entity.class);
When converting Object -> JSON the description string is nested because the @JsonRawValue is set:
{"name":"MyName","descriptionJson":{ "abc": 123 }}
However, when I call the Jackson mapper.readValue function to read the JSON string back into an entity object I get the exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException:
Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
at [Source: (String)"{"name":"MyName","descriptionJson":{ "abc": 123 }}"; line: 1, column: 36] (through reference chain: com.test.Entity["descriptionJson"])
Given that the @JsonRawValue annotation exists, how would you recommend marshalling the created JSON string back into to Entity object? Is there another annotation I'm missing?
Thanks
Upvotes: 4
Views: 11748
Reputation: 3766
@JsonRawValue
is intended only sor serializatio from docs:
Marker annotation that indicates that the annotated method or field should be serialized by including literal String value of the property as is, without quoting of characters.
To solve your problem you can try
public class Entity {
@Getter
@Setter
private String name;
private String descriptionJson;
@JsonRawValue
public String getDescriptionJson() {
return descriptionJson;
}
public void setJson(JsonNode node) {
this.descriptionJson = node.toString();
}
}
Upvotes: 0
Reputation: 91
For one of my requirements I used field type as Map to store Json as it is. This way I was able to read the nested JSOn as Map and when I serialize object to JSON, it came up correctly. Below is the example.
Entity.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Entity {
public int id=0;
public String itemName="";
public Map<String,String> owner=new HashMap<>();
}
Temp.java
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class Temp {
public static void main(String[] args){
ObjectMapper objectMapper= new ObjectMapper();
try {
Entity entity
=objectMapper.readValue(Temp.class.getResource("sample.json"), Entity.class);
System.out.println(entity);
String json=objectMapper.writeValueAsString(entity);
System.out.println(json);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sample.json
{
"id": 1,
"itemName": "theItem",
"owner": {
"id": 2,
"name": "theUser"
}
}
Upvotes: 1
Reputation: 1103
@JsonRawValue is intended for serialization-side only, but in this problem you can do like this:
@Getter
@Setter
public class Entity {
private String name;
@JsonRawValue
private String descriptionJson;
@JsonProperty(value = "descriptionJson")
public void setDescriptionJsonRaw(JsonNode node) {
this.descriptionJson = node.toString();
}
}
This problem is repeated with How can I include raw JSON in an object using Jackson?.
Upvotes: 4
Reputation: 153
You can use ObjectMapper
from Jackson 2 as follows:
ObjectMapper mapper = new ObjectMapper();
String jsonStr = "sample json string"; // populate this as required
MyClass obj = mapper.readValue(jsonStr,MyClass.class)
try escaping the curly braces in the description json's value.
Upvotes: 0