臣接孙氏道:
@POST
@Path("log")
public Map<String, List<OperationResult>> log(Stats stats) {
..
}
{
"eventType": 1
"params": {
"field1" : 10
}
}
{
"eventType": 2
"params": {
"field2" : "ten"
}
}
interface Params;
class Params1 implements Params{ public int field1; }
class Params2 implements Params{ public String field2; }
class Stats {
public int eventType;
public Params params;
}
我如何使Jersey解析JSONs,以便如果eventType=1,那么stats.params变成Params1的实例,而else变成params2的实例?
今天早上我花了点时间来解决这个问题。一个有趣的用途。我想出了如何做到这一点,但我必须稍微更改您的json。这并不是绝对必要的,但是类型转换不是您问题的一部分,因此如果需要,我们可以执行后续操作:)
您的JSON:
artur@pandaadb:~/tmp/test$ cat 1.json
{
"eventType": "1",
"params": {
"field1" : 10
}
}
artur@pandaadb:~/tmp/test$ cat 2.json
{
"eventType": "2",
"params": {
"field2" : "10"
}
}
我正在使用这两个文件来执行请求。注意,我将eventType t改为字符串而不是数字。我稍后会指出这点。
public class Stats {
@JsonProperty
int eventType;
public Params params;
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="eventType")
@JsonSubTypes({ @Type(value = Param1.class, name = "1"), @Type(value = Param2.class, name = "2") })
public void setParams(Params params) {
this.params = params;
}
}
JsonTypeInfo.Id.NAME
JsonTypeInfo.As.EXTERNAL_PROPERTY
property="eventType"
只是告诉jackson要使用什么属性名称
然后在JsonSubTypes中注释可能的选项,在您的示例中为2:
@Type(value = Param1.class, name = "1")
这告诉jackson在eventType属性为“1”的情况下使用param1.class。
注这就是我稍微更改json的原因。子类型批注不能将整数作为属性。现在,您可以使用不同的选项,例如TypeConverters,它在运行时将您的integer属性转换为string,这样您就可以保持json不变。我跳过了这一步,一个快速的谷歌会给你如何做到这一点的指导。
现在您的参数模型如下所示:
public interface Params {
public static class Param1 implements Params {
@JsonProperty
int field1;
}
public static class Param2 implements Params {
@JsonProperty
String field2;
}
}
我正在注释这些属性以便杰克逊知道去序列化那些。
JsonTypeInfo.As.EXTERNAL_PROPERTY
JsonTypeInfo.As.EXISTING_PROPERTY
最后是测试:
artur@pandaadb:~/tmp/test$ curl -XPOST "localhost:8085/api/v2/test" -d @1.json -H "Accept: application/json" -H "Content-Type: application/json"
io.gomedia.resource.Params$Param1
artur@pandaadb:~/tmp/test$
artur@pandaadb:~/tmp/test$ curl -XPOST "localhost:8085/api/v2/test" -d @2.json -H "Accept: application/json" -H "Content-Type: application/json"
io.gomedia.resource.Params$Param2
请注意,资源正在打印实例化类的名称。正如您所看到的,这两个json都被反序列化到了正确的实例类中。
我希望这会有所帮助:)
但是,为了完整起见,如果您需要一个转换器(因为您可能需要它将字符串模型转换回一个整数以进行序列化),这将是一个整数到字符串转换器:
public class EventTypeConverter implements Converter<Integer, String>{
@Override
public String convert(Integer value) {
return String.valueOf(value);
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return SimpleType.construct(Integer.class);
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return SimpleType.construct(String.class);
}
}
您可以通过执行以下操作来使用它:
@JsonProperty
@JsonDeserialize(converter=EventTypeConverter.class)
String eventType;
好的,我知道有一堆类似的问题,但似乎都行不通。 我为我的实体设置了以下结构。 在我的控制器中,我尝试将一个请求映射到下面的方法。 请尝试%1 我认为它是这样做的--添加了一个元数据属性,该属性将存储子类类。 结果是什么。 结果是什么。 即使将和添加到这两个子类中,也会得到相同的结果。 其他尝试 我试了很多。什么都不起作用。不会包含这里的所有内容。 我觉得应该有一个简单的方法来做到这一点,但我只是不
问题内容: 我正在尝试制作一个使用Jackson来反序列化POJO的类。 看起来像这样… 我对此实施有2个问题。 首先是我将类类型传递给方法,以便对象映射器知道应反序列化的类型。有使用泛型的更好方法吗? 同样在get方法中,我将一个从objectMapper返回的对象强制转换为T。这看起来特别讨厌,因为我必须在此处强制转换T,然后还必须从调用它的方法中强制转换对象类型。 我在该项目中使用了Robo
我看过jackson反序列化@JsonTypeInfo的一个例子,那就是: 我试过了,效果很好。现在的问题是,在示例类中,Cat和Dog是从Animal中引用的,我想避免这种情况。有没有一种方法可以将类型绑定从类动物中移除,并且仍然进行反序列化工作?谢谢
假设我有以下格式的JSON: 我试图避免自定义反序列化程序,并试图将上述JSON(称为Wrapper.java)反序列化为JavaPOJO。“type”字段指示“object”反序列化,即type=foo表示使用foo.java反序列化“object”字段。(如果type=Bar,则使用Bar.java反序列化对象字段)。Metadata/owner将始终以相同的方式对每个元数据使用简单的带Jac
在下面的示例中,我有一个主类-A和它的子类-B。两者都可以用作一般类X中的属性。 如何使用Jackson多态特性将以下给定的json正确反序列化为各自的类: JSON A: JSON B: 预期结果:将keys对象映射到JSON A的类A和JSON B的类B。 请提出其他建议。