1

次のようなjacksonを使用してJSON文字列を解析しようとしています。

{
  "name":"John",
  "Wrapper":{
    "id":0
   }
}

のために別のJavaクラスを作成する必要がないようにWrapperし、代わりにそれを整数にマップしようとしています。@XmlElementWrapperドキュメントに次のように記載されていても、使用してみました。

これは主に、コレクションのラッパーXML要素を生成するために使用することを目的としています。

しかし、それは機能しません。次の例外が発生します。

Exception in thread "main" org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.lang.Integer out of START_OBJECT token
 at [Source: java.io.StringReader@44eefb4; line: 1, column: 15] (through reference chain: Test["Wrapper"])
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:219)
    at org.codehaus.jackson.map.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:305)
    at org.codehaus.jackson.map.deser.std.StdDeserializer$IntegerDeserializer.deserialize(StdDeserializer.java:795)
    at org.codehaus.jackson.map.deser.std.StdDeserializer$IntegerDeserializer.deserialize(StdDeserializer.java:782)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
    at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:579)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2723)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1854)
    at Test.main(Test.java:37)

実行可能な例を次に示します。

@XmlAccessorType(XmlAccessType.FIELD)
public class Test {

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
        String json = 
                "{" +
                "\"name\":\"John\","+
                "\"Wrapper\":{"+
                "   \"id\":0}"+
                "}";
        ObjectMapper mapper = new ObjectMapper();
        mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector());
        mapper.setSerializationInclusion(Inclusion.NON_NULL);
        Test test = mapper.readValue(json, Test.class);
        System.out.println(test.toString());
    }

    @XmlElement(name="name")
    private String name;

    @XmlElementWrapper(name="Wrapper")
    @XmlElement(name="id")
    private Integer wrapperId;

    @Override
    public String toString() {
        return "Test [name=" + name + ", wrapperId=" + wrapperId + "]";
    }

}
4

1 に答える 1

1

Jacksonは、限られた数の構造体変換アノテーション(@JsonUnwrapped、ルート値のラッピング)を提供していますが、このユースケースには適していません。この特定のユースケースには、実際には機能のリクエストがあると思います(そうなる@JsonWrappedと思います)。

価値のあることとして、Jackson JAXBアノテーションモジュールはアノテーションを認識しますが、JSONには使用されません(XMLバックエンドに使用されますがCollection、配列値のプロパティにのみ使用されます)。

単純な静的クラスを追加するだけWrapperです。または、それが一般的なイディオムである場合は、共有ジェネリッククラスWrapper<T>であり、すべての種類のラップされた値に使用します。コードの量は単純で、オブジェクト構造はJSONデータ構造と1対1で一致します。

于 2012-11-19T04:16:58.487 に答える