Jersey を使用して Facebook に対してバッチ リクエストを実行しようとしています。問題は、Facebook が最も奇妙な構造 (JSONObject と JSONString の混合) を返すことです。
[
{
"code": 200,
"headers": [
{
"name": "Access-Control-Allow-Origin",
"value": "*"
},
<!-- some more headers... -->
],
"body": "{\n \"message\": \"Hello World!\",\n \"id\": \"...\",\n \"created_time\": \"2012-10-17T07:18:02+0000\"\n
<!-- ... -->
}"
}
]
Jackson を使用してObjectMapper
この混乱を逆シリアル化しようとすると、
JsonMappingException: Can not instantiate value of type [simple type, class package.to.Post] from JSON String; no single-String constructor/factory method (through reference chain: package.to.BatchResult["body"])
これは私が使用している POJO 構造です。
public class BatchResult<T> {
private T body;
private int code;
private List<BatchResultHeader> headers;
// ...
}
public class BatchResultHeader {
private String name;
private String value;
// ...
}
public class Post {
private String message;
// ...
}
このようにバッチリクエストを送信します。Params には、ドキュメントで定義されているバッチ パラメーターとバッチ リクエストが含まれています。また、バッチ リクエストの POST 呼び出しも必要です。したがって、結果のJSON は期待どおりであるため、呼び出しは問題ないはずです(上記を参照)。
Client client = Client.create();
WebResource webResource = client.resource("https://graph.facebook.com");
ClientResponse response = webResource.type("application/x-www-form-urlencoded")
.post(ClientResponse.class, params);
String json = response.getEntity(String.class);
今、私は逆シリアルObjectMapper
化するために使用します:
TypeReference<List<BatchResult<Post>>> ref = new TypeReference<List<BatchResult<Post>>>(){});
ObjectMapper mapper = new ObjectMapper();
List<BatchResult<Post>> batchResults = mapper.readValue(json, ref);
@JsonCreatorを使用していますか?
したがって、この例外を検索すると、コンストラクターで@JsonCreator
注釈を使用するという提案が見つかりました。Post
しかし、それは
java.lang.IllegalArgumentException: Argument #0 of constructor [constructor for package.to.Post, annotations: {interface org.codehaus.jackson.annotate.JsonCreator=@org.codehaus.jackson.annotate.JsonCreator()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator
これに対する解決策は、POJO の各プロパティに個別に注釈を付けることであると思われます。それが私が言ったポイントです。
したがって、疑問が残ります:おそらく ObjectMapper 設定を使用して、このミックスを逆シリアル化する方法はありますか?
または、Jersey に、フォーマットされた受信文字列をフィルタリングし、すべての空白をカットしてから、逆シリアル化のために Jackson に送信するように指示できますか?
私の不満な回避策:
BatchResult
クラスに であるbody
と伝えるとString
、それは機能し、 . で BatchResult を取得しString
body
ます。正しく逆シリアル化するタイプでObjectMapper
もう一度使用します。これは私の現在の解決策ですが、見た目が乱雑で、デシリアライゼーションの結果を反復してその要素をデシリアライズするのは私の仕事ではありません...なぜジャクソンはこれを自分で理解できないのですか?String
body
Post.class