1

JSON 応答がオブジェクトまたはオブジェクトの配列になるという問題が発生しています

単一の値を持つ Foobar の例:

{
    "foo": {"msg": "Hello World" }
}

配列を使用した Foobar の例:

{
    "foo": [
           { "msg": "Hello World" },
           { "msg": "Goodbye World" }
         ]
}

単一の値を任意の配列に強制したいのですが、これまでのところ、すべての単一の値を配列として変換する唯一の方法が見つかりました。


ACCEPT_SINGLE_VALUE_AS_ARRAY

http://wiki.fasterxml.com/JacksonFeaturesDeserialization


単一のプロパティに対して同じことを行う注釈を探していましたが、これまでのところ、Google は例を見つけていません。

以前にこの問題に遭遇した人はいますか?私は本当にすべてを配列として書き直して、バグのあるサービスで RestTemplate を動作させたくありません。

4

3 に答える 3

7

単一の値を任意の配列に強制したいのですが、これまでのところ、すべての単一の値を配列として変換する唯一の方法が見つかりました。

これは単にそうであってはなりません。ACCEPT_SINGLE_VALUE_AS_ARRAYプロパティ、特定のObjectMapper に対してオン/オフですが、その動作は、JSON 値がマップされているターゲット プロパティによって完全に制御されます。

  • ACCEPT_SINGLE_VALUE_AS_ARRAY がオンの場合、JSON 値を Java コレクション プロパティにマッピングしてもエラーになりません。
  • ACCEPT_SINGLE_VALUE_AS_ARRAY がオンの場合、JSON 値を Java 基本プロパティにマッピングしても (また) エラーにはなりません。

次のコードで説明します。

class Foo {
    private String msg;

    // Constructor, setters, getters
}

class Holder {
    private List<Foo> foo;
    private Foo other;

    // Constructors, setters, getters
}

public class FooTest {

    @org.junit.Test
    public void testCollectionFromJSONValue() throws Exception {
        final InputStream stream = Thread.currentThread()
                .getContextClassLoader().getResourceAsStream("foo.json");

        final String json = IOUtils.toString(stream);

        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(
                DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY,
                true);
        final Holder holder = mapper.readValue(json, Holder.class);
        System.out.println(holder);
    }
}

次の JSON に依存します。

{
    "foo": {
        "msg": "Hello World"
    },
    "other": {
        "msg": "Goodbye"
    }
}

コードを実行すると、「foo」プロパティが正常にリストに逆シリアル化され、「other」プロパティが (基本的な) Foo 型に逆シリアル化されることが示されます。

于 2013-04-09T19:51:35.957 に答える
1

私は同じ問題を抱えていて、一般的に RestTemplate をそのように構成するための解決策を見つけるのに苦労しました。objectMapper を常にインスタンス化して変更したいわけではないので、私の解決策は次のとおりです。

<bean id="myRestTemplate" class="org.springframework.web.client.RestTemplate">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper" ref="jacksonObjectMapper" />
            </bean>
        </list>
    </property>
</bean>
<bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="jacksonObjectMapper" />
    <property name="targetMethod" value="configure" />
    <property name="arguments">
        <list>
            <value type="com.fasterxml.jackson.databind.DeserializationFeature">ACCEPT_SINGLE_VALUE_AS_ARRAY</value>
            <value>true</value>
        </list>
    </property>
</bean>

次に、この事前構成された RestTemplate をコードに挿入して使用できます。

@Autowired
private RestTemplate myRestTemplate;
于 2015-06-01T08:52:40.127 に答える