如何忽略json的父标记?
这是我的json
String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}";
这是从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;
}
}
这是测试 公共课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);
}
我收到错误::
org.codehaus.jackson.map.JsonMappingException: Root name 'parent' does not match expected ('RootWrapper') for type [simple type, class MavenProjectGroup.mavenProjectArtifact.RootWrapper]
我找到了Jackson注释::
给出的解决方案 (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);
工作完成!!
杰克逊反序列化方式的另一个打嗝:(
如果'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE配置',它解包所有jsons,尽管我的类没有注释@JsonRootName(value =“rootTagInJson”),但是没有被安装。
我想仅在使用@JsonRootName注释类时解包根标记,否则不要打开。
以下是解包根标记的用例。
###########################################################
Unwrap only if the class is annotated with @JsonRootName.
############################################################
我对Jackson源代码的ObjectMapper进行了一些小改动,并创建了一个新版本的jar。 1.将此方法放在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.
答案 0 :(得分:32)
从https://github.com/FasterXML/jackson-databind中的TestRootName.java中获取的示例可能会提供更好的方法。特别是使用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);
}
答案 1 :(得分:13)
我在Spring中开发了一个类似的问题来开发一个restful应用程序。我必须支持一个非常异构的API,其中一些有根元素,另一个没有。我找不到比实时配置此属性更好的解决方案。遗憾的是,没有人支持杰克逊的每一级根元素展开。无论如何,有人可能会觉得这很有用。
@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);
}
}
答案 2 :(得分:0)
作为Seagabond的更新帖子,如果你想在写参数值时有相同的效果,你可以覆盖其他的写方法。
@Component
public class ObjectMapper extends com.fasterxml.jackson.databind.ObjectMapper {
private void autoconfigureFeatures(Object value) {
JavaType javaType = _typeFactory.constructType(value.getClass());
autoconfigureFeatures(javaType);
}
private void autoconfigureFeatures(JavaType javaType) {
Annotation rootAnnotation = javaType.getRawClass().getAnnotation(JsonRootName.class);
this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, rootAnnotation != null);
}
@Override
public void writeValue(DataOutput out, Object value) throws IOException {
autoconfigureFeatures(value);
super.writeValue(out, value);
}
@Override
public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException, JsonMappingException {
autoconfigureFeatures(value);
super.writeValue(w, value);
}
@Override
public byte[] writeValueAsBytes(Object value) throws JsonProcessingException {
autoconfigureFeatures(value);
return super.writeValueAsBytes(value);
}
@Override
public String writeValueAsString(Object value) throws JsonProcessingException {
autoconfigureFeatures(value);
return super.writeValueAsString(value);
}
@Override
protected Object _readMapAndClose(JsonParser jsonParser, JavaType javaType) throws IOException, JsonParseException, JsonMappingException {
autoconfigureFeatures(javaType);
return super._readMapAndClose(jsonParser, javaType);
}
}
答案 3 :(得分:0)
非常简单:
创建对象映射器的实例并启用包装和展开根值
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
向您的DTO添加
@JsonRootName("yourname")
注释
@JsonRootName("root")
public class YourDto {
// ...
}
答案 4 :(得分:0)
我也遇到了这种类型的问题。我在配置类中添加了以下代码行,其中定义了 RestTemplate 及其 MessageConverters 的配置。
Annotation rootAnnotation = mapper.getTypeFactory().getClass().getAnnotation(JsonRootName.class); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, Objects.nonNull(rootAnnotation));
基本上这个配置将帮助 Mapper 识别提供的类是否用“@JsonRootName”注释,如果没有,则不需要搜索根。 希望它会帮助你和其他人。