我有以下工作代码可以反序列化JSON消息。如您所见,JSON消息的根名称为“ response”,我也相应地对Response类进行了注释以表明这一点。但是,实际上,JSON消息将从其他系统接收,并且根名称可以是“ response”之外的任何名称。如何处理不同的根名称?
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public static void main(String... args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String responseMessage =
"{" +
" \"response\" : {" +
" \"body\" : {" +
" \"country\" : \"Vietnam\"" +
" }" +
" }" +
"}";
Response response = mapper.readValue(responseMessage, Response.class);
}
}
class Body {
private String country;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
@JsonTypeName("response")
@JsonTypeInfo(include = As.WRAPPER_OBJECT, use = Id.NAME)
class Response {
private Body body;
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
答案 0 :(得分:0)
简单的答案是将其反序列化为Map<String, Body>
。要手动执行此操作,您需要使用以下代码:
mapper.readValue(response, new TypeReference<Map<String, Body>>() {})
请注意,如果您使用的是像Spring这样的框架(通常应该这样),则应该让该框架为您处理序列化。
答案 1 :(得分:0)
您可以通过两种方式解决此问题
将Response,Body类设为静态
static class Body {
private String country;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
@JsonTypeName("response")
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
static class Response {
private Body body;
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
或
将响应和身体类别设为公开
public class Body {
private String country;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
和
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeName("response")
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
public class Response {
private Body body;
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
然后调用主方法
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String responseMessage =
"{" +
" \"response\" : {" +
" \"body\" : {" +
" \"country\" : \"Vietnam\"" +
" }" +
" }" +
"}";
Response response = mapper.readValue(responseMessage, Response.class);
System.out.println(response.getBody().getCountry());
}
问题原因:
杰克逊拒绝尝试使用非静态内胆的基本原因 反序列化的类(序列化实际上可以正常工作)是 因为没有通用的方法来实例化此类-那里 不是零参数构造函数,也不是@JsonCreator注释其他 构造函数或工厂方法(或单字符串参数) 构造函数,但我离题了)。杰克逊无法实例化它们。
理论上,如果知道 封闭父类实例是。但实际上这两者都是 复杂且不必要的-通常省略“静态”是 可以是偶然的,也可以是偶然的,可以添加来制作东西 工作。
参考:http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html
答案 2 :(得分:0)
您可以编写自定义反序列化程序,以跳过包装程序或使用@JsonAnySetter
注释。参见以下示例:
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String responseMessage =
"{ \"response\" : {"
+ " \"body\" : {"
+ " \"country\" : \"Vietnam\""
+ " }"
+ " }"
+ "}";
Response response = mapper.readValue(responseMessage, Response.class);
System.out.println(response.getBody());
}
}
class Body {
private String country;
// getters, setters, toString
}
class Response {
private Body body;
@JsonAnySetter
public void setAny(String anyPropertyName, Map<String, Body> body) {
for (Body item : body.values()) {
this.body = item;
}
}
// getters, setters
}
上面的代码显示:
Body{country='Vietnam'}