有一个函数可以返回JSON格式的元素列表。从包含后代类型元素的结果中读取内容时会出现问题。
例如,请考虑以下定义:
public class Fruits {
public String description;
public List<Fruit> fruits = new ArrayList<Fruit>();
}
public class Fruit {
public String name;
public int pieces;
}
public class Banana extends Fruit {
public String origin;
}
@ApplicationScoped
@Provider
@Produces("application/json")
@Path("/fruit")
public class MyRestService {
@GET
@Path("/fruits")
public Fruits getFruits() {
Fruits myFruits = new Fruits();
myFruits.description = "My fruits";
Fruit myApple = new Fruit();
myApple.name = "apple";
myApple.pieces = 8;
myFruits.fruits.add(myApple);
Banana myBanana = new Banana();
myBanana.name = "banana";
myBanana.pieces = 5;
myBanana.origin = "Ecuador";
myFruits.fruits.add(myBanana);
return myFruits;
}
}
生成的JSON如下:
{
"description":"My fruits",
"fruits":[
{
"name":"apple",
"pieces":8
},
{
"name":"banana",
"pieces":5,
"origin":"Ecuador"
}
]
}
假设我们在content
变量中得到了这个结果。我想按如下方式解析它:
ObjectMapper objectMapper = new ObjectMapper();
Fruits fruits = objectMapper.readValue(content, Fruits.class);
抛出以下异常:
Exception in thread "main" org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "origin" (Class myresttest.Fruit), not marked as ignorable
at [Source: java.io.StringReader@38653ad5; line: 1, column: 104] (through reference chain: myresttest.Fruits["fruits"]->myresttest.Fruit["origin"])
是否有可能在不触及服务器代码的情况下克服此问题?
答案 0 :(得分:2)
我建议您使用 json-simple-1.1.1
你可以像这样得到JSonObject:
JSONObjec requestobj = (JSONObject) JSonValue.parse(request) ;
注意:请求值应该是JSON的String表示形式。
然后将requestobj字段解析为新的Fruits实例... 例如:
Fruits myFruits = new Fruits();
myFruits.description = (String) requestobj.getString("description");
答案 1 :(得分:1)
首先,我相信你使用的是杰克逊的旧版本。至少在三年前,org.codehaus.jackson
被com.fasterxml.jackson
感动了。你仍然可以使用它,但我建议使用支持的版本(如果可能的话)。
当你定义List Jackson时,问题并不知道任何关于Fruit的任何子类的问题。要通知Jackson这个类有子类,而你不想从它们中删除数据,你需要添加@JsonTypeInfo和@JsonSubTypes。
class Fruits {
public String description;
public List<Fruit> fruits = new ArrayList<Fruit>();
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", defaultImpl = Fruit.class)
@JsonSubTypes({@JsonSubTypes.Type(value = Fruit.class, name = "fruit"),
@JsonSubTypes.Type(value = Banana.class, name = "banana")})
class Fruit {
public String name;
public int pieces;
}
class Banana extends Fruit {
public String origin;
}
请注意,它会将生成的JSON更改为:
{
"description": "My fruits",
"fruits": [
{
"type": "fruit",
"name": "apple",
"pieces": 8
},
{
"type": "banana",
"name": "banana",
"pieces": 5,
"origin": "Ecuador"
}
]
}
请注意,此JSON现在有一个额外的字段type
,Jackson将使用它来确定需要使用哪个子类来反序列化JSON。
您可以更改此属性名称以及Jackson如何将额外信息包含到JSON中。您可以在此处详细了解:http://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html?is-external=true