How to ignore parent tag from json??
Here is my json
String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}";
And here is the class to be mapped from json.
public class RootWrapper { private List<Foo> foos; public List<Foo> getFoos() { return foos; } @JsonProperty("a") public void setFoos(List<Foo> foos) { this.foos = foos; } }
Here is the test public class JacksonTest {
@Test public void wrapRootValue() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}"; RootWrapper root = mapper.readValue(str, RootWrapper.class); Assert.assertNotNull(root); }
I get the error ::
org.codehaus.jackson.map.JsonMappingException: Root name 'parent' does not match expected ('RootWrapper') for type [simple type, class MavenProjectGroup.mavenProjectArtifact.RootWrapper]
I found the solution given by Jackson annotation::
(a) Annotate you class as below @JsonRootName(value = "parent") public class RootWrapper { (b) It will only work if and only if ObjectMapper is asked to wrap. ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
Job Done!!
Another hiccup with Jackson way of Deserialization :(
if 'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE configured', it unwrap all jsons, eventhough my class in not annotated with @JsonRootName(value = "rootTagInJson"), isn't weired.
I want to unwrap root tag only if the class is annotated with @JsonRootName otherwise, don't unwrap.
So below is the usecase for unwrap root tag.
########################################################### Unwrap only if the class is annotated with @JsonRootName. ############################################################
I did a small change in ObjectMapper of Jackson source code and created a new version of jar. 1. Place this method in ObjectMapper
// Ash:: Wrap json if the class being deserialized, are annotated // with @JsonRootName else do not wrap. private boolean hasJsonRootName(JavaType valueType) { if (valueType.getRawClass() == null) return false; Annotation rootAnnotation = valueType.getRawClass().getAnnotation(JsonRootName.class); return rootAnnotation != null; } 2. Edit ObjectMapper method :: Replace cfg.isEnabled(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE) with hasJsonRootName(valueType) 3. Build your jar file and use it.
How to ignore parent tag from json?? String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}"; And here is the class to be mapped from json. (a) Annotate you class as below @JsonRootName(value = "parent") public class RootWrapper { (b) It will only work if and only if ObjectMapper is asked to wrap.
If there are fields in Java objects that do not wish to be serialized, we can use the @JsonIgnore annotation in the Jackson library. The @JsonIgnore can be used at the field level, for ignoring fields during the serialization and deserialization.
@JsonRootName allows to have a root node specified over the JSON. We need to enable wrap root value as well.
An example taken from TestRootName.java in https://github.com/FasterXML/jackson-databind may give a better way of doing this. Specifically using withRootName(""):
private ObjectMapper rootMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true); mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); return mapper; } public void testRootUsingExplicitConfig() throws Exception { ObjectMapper mapper = new ObjectMapper(); ObjectWriter writer = mapper.writer().withRootName("wrapper"); String json = writer.writeValueAsString(new Bean()); assertEquals("{\"wrapper\":{\"a\":3}}", json); ObjectReader reader = mapper.reader(Bean.class).withRootName("wrapper"); Bean bean = reader.readValue(json); assertNotNull(bean); // also: verify that we can override SerializationFeature as well: ObjectMapper wrapping = rootMapper(); json = wrapping.writer().withRootName("something").writeValueAsString(new Bean()); assertEquals("{\"something\":{\"a\":3}}", json); json = wrapping.writer().withRootName("").writeValueAsString(new Bean()); assertEquals("{\"a\":3}", json); bean = wrapping.reader(Bean.class).withRootName("").readValue(json); assertNotNull(bean); }
I experienced a similar problem developing a restful application in Spring. I had to support a very heterogeneous API, some of it had root elements, another did not. I could not find a better solution than to configure this property realtime. It's a great pity there is no support for per-class root element unwrapping in Jackson. Anyway, somebody may find this helpful.
@Component public class ObjectMapper extends com.fasterxml.jackson.databind.ObjectMapper { private void autoconfigureFeatures(JavaType javaType) { Annotation rootAnnotation = javaType.getRawClass().getAnnotation(JsonRootName.class); this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, rootAnnotation != null); } @Override protected Object _readMapAndClose(JsonParser jsonParser, JavaType javaType) throws IOException, JsonParseException, JsonMappingException { autoconfigureFeatures(javaType); return super._readMapAndClose(jsonParser, javaType); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With