我正在尝试使用 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
<!-- ... -->
}"
}
]
现在,当我尝试使用杰克逊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
是 aString
时,它可以工作并且我得到一个带有String
body
. 现在ObjectMapper
再次使用它正确反序列String
body
化的Post.class
类型。这是我当前的解决方案,但它看起来很混乱,我的工作不应该是迭代反序列化结果以反序列化其元素......为什么杰克逊不能自己解决这个问题?