私はjsonベースのREST Webサービスを使用して実装しています:Jetty、Jersey、Jersey-JSONをJacksonを使用して実装しています。
私のメソッドの1つは、List <String>型のフィールドを持つPersonインスタンスを受け取ります。例:
Public class Person {
List<String> names;
}
名前の配列で呼び出すと、すべて正常に機能します。例えば。:
{ "names" : [ "Jhon", "Doe" ] }
しかし、その人の名前が1つしかない場合、クライアントは次のように単一の値要素を作成します。
{ "names" : "Jhon" }
単一の値でサービスを呼び出そうとすると、例外が発生します。
Can not deserialize instance of Java.util.ArrayList out of VALUE_STRING token
質問:
配列フィールドが単一の要素として送信されたときに配列フィールドを非直列化できるようにするには、Webサービスをどのように作成/構成する必要がありますか?.
-
私はすでに読んだ:
Jackson逆シリアル化-含まれているArrayList <T>を使用
そして
JAXBオブジェクトのリストのシリアル化をJSONにカスタマイズするにはどうすればよいですか?
そしてこれは最後の答えを参照します:
ジャージークライアントは、jsonサービスをデシリアライズできません-例外(インスタンスをデシリアライズできません)
しかし、それらのどれも問題を解決しません。
前もって感謝します!
長い一日のあと、また...たくさんのウィキやFAQを読んだ後、ようやく動きました。
私がしたこと:
物語:
デフォルトでjaxb(I belive)を使用するJersey 1.13を使用していました。
私はそれをジャクソンを使うように変更しました
<init-param>
<param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
で説明されているように:
https://stackoverflow.com/a/13895768/66099
これにより、私のジャージはジャクソンを使用しましたが、問題は残っています。ジャクソンはまだ配列をデシリアライザできません。
Jacksonプロバイダーの使用を強制しました:
<init-param>
<param-name>com.Sun.jersey.config.property.packages</param-name>
<param-value>
your.project.packages;
org.codehaus.jackson.jaxrs</param-value>
</init-param>
https://stackoverflow.com/a/3143214/66099
必要なステップでしたが、十分ではありませんでした。 ACCEPT_SINGLE_VALUE_AS_ARRAYフラグを有効にする必要があります。
ObjectMapper objectMapper;
objectMapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
カスタムデシリアライザを定義する必要がありました
public class MyResolver implements ContextResolver<ObjectMapper> {
@Override
public ObjectMapper getContext(final Class<?> objectType) {
...
return objectMapper;
}
}
それを行うには:
これをすべて行った後も、それはうまくいきませんでした...
さらに検索を行ったところ、次のことがわかりました。
依存関係の問題について議論しています。
これは私の問題を明らかにしました、Jersey v1.13はJackson v1.9.2と共に出荷されますJackson v2.0が必要です
ジャクソン1.9.2が含まれていたため、jersey-jsonの依存関係を削除しました。
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</dependency>
そして直接依存関係を宣言します:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
参照:
注:この変更により、Jaxbまたはjettisonを使用するJersey機能が削除されます。
オフトピック、誰かにとって興味深いかもしれません:
JSONフィールドの命名に@XmlElementフィールドアノテーションを使用しないようにJersey/Jacksonを設定
JsonFormat アノテーションを使用して、クラス、フィールド、またはメソッドレベルのアノテーションでこれを行うことができます
@JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
protected List<String> list;
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
このページ の例5.10および5.11は、正確な問題を説明しています。次のように、JSONビルダーを構成して単一アイテムリストの配列を強制できます:JSONConfiguration.mapped().arrays("names").build()
。
クラスに@JsonSerializeを追加することでうまくいきました
@JsonSerialize
Public class Person {
List<String> names;
}
{"results": {"place": {"lang": "en-US","woeid": "2168606"}}}
&
{"results": {"place": [{"lang": "en-US","woeid": "2168606"}, {"lang": "en-US","woeid": "2168606"}]}}
このタイプの方法... yahoo place apiを使用する場合