杰克逊(Jackson):未识别的字段

42

我使用jackson将JSON转换为对象类。

JSON:

{
    "aaa":"111",
    "bbb":"222", 
    "ccc":"333" 
}

对象类:

class Test{
    public String aaa;
    public String bbb;
}

代码:

ObjectMapper mapper = new ObjectMapper();
Object obj = mapper.readValue(content, valueType);

我的代码抛出了这样的异常:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "cccc" (Class com.isoftstone.banggo.net.result.GetGoodsInfoResult), not marked as ignorable

我不想给类Test添加一个属性,我只希望jackson转换已经存在于Test中的值。

5个回答

80

Jackson提供了几种不同的机制来配置处理“额外”的JSON元素。以下是一种配置ObjectMapper以不触发FAIL_ON_UNKNOWN_PROPERTIES的示例。

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    // { "aaa":"111", "bbb":"222", "ccc":"333" }
    String jsonInput = "{ \"aaa\":\"111\",
                          \"bbb\":\"222\",
                          \"ccc\":\"333\" }";

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD,
                         Visibility.ANY);
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,
                     false);

    Test test = mapper.readValue(jsonInput, Test.class);
  }
}

class Test
{
  String aaa;
  String bbb;
}

其他方法请参见http://wiki.fasterxml.com/JacksonHowToIgnoreUnknown


27
请注意,对于2.x版本,您应该使用mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Supr

41

从 Jackson 2.0 开始,内部枚举 (DeserializationConfig.Feature) 被移动到独立的枚举 (DeserializationFeature) 中:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


21
如果您正在使用Jackson 2.0(fasterxml)
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

10

提前注意模型的重要变化,可能导致业务逻辑崩溃。

为了更好地控制应用程序,最好手动处理此异常。

objectMapper.addHandler(new DeserializationProblemHandler() {

            @Override
            public boolean handleUnknownProperty(DeserializationContext ctxt,
                    JsonParser jp, JsonDeserializer<?> deserializer,
                    Object beanOrClass, String propertyName)
                    throws IOException, JsonProcessingException {

                String unknownField = String.format("Ignoring unknown property %s while deserializing %s", propertyName, beanOrClass);
                Log.e(getClass().getSimpleName(), unknownField);
                return true;
            }
        });

返回true以处理UnrecognizedPropertyException

不要默默忽略未识别的字段。


我认为只说“不要”太宽泛了。当涉及到 API 和对版本变化的灵活性时,我很喜欢 Postel 的法则。 https://en.wikipedia.org/wiki/Robustness_principle - Matt Broekhuis
1
虽然有点晚了,但这是一个好答案。@MattBroekhuis 这个答案不与Postel法则冲突,并且它是灵活的。它所做的是给某个人在某个地方一个机会去弄清楚为什么API没有像预期的那样处理某些东西,而不是简单地隐藏有用的信息。 - PDH

1
根据这份文档,您可以使用Jackson2ObjectMapperBuilder类来构建您的ObjectMapper。这个Jackson2ObjectMapperBuilder可以在spring-web依赖包中找到。请注意保留HTML标签。
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder

@Autowired
Jackson2ObjectMapperBuilder objectBuilder;

ObjectMapper mapper = objectBuilder.build();
String json = "{\"id\": 1001}";

Jackson2ObjectMapperBuilder默认情况下禁用未识别属性异常错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接