尝试使用Jersey和Genson执行POST调用时遇到以下问题:
....
com.owlike.genson.JsonBindingException:找不到类型为Animal的构造函数
....
我有以下设置:
-> Animal.java
package com.test;
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes( {@JsonSubTypes.Type(value = Dog.class, name = "dog") })
public interface Animal
{ }
-> Dog.java
package com.test;
import org.codehaus.jackson.annotate.JsonTypeName;
import org.codehaus.jackson.annotate.JsonProperty;
@JsonTypeName("dog")
public class Dog implements Animal
{
@JsonProperty
public String name;
public String getName() { return name; }
public void setName(String n) { this.name = n; }
}
-> Zoo.java
package com.test;
import java.util.List;
public class Zoo
{
private List<Animal> animals;
public List<Animal> getAnimals()
{
return animals;
}
public void setAnimals(List<Animal> animals)
{
this.animals = animals;
}
}
-> GensonCustomResolver.java
package com.test;
import javax.ws.rs.next.ContextResolver;
import javax.ws.rs.next.Provider;
import com.owlike.genson.Genson;
@Provider
public class GensonCustomResolver implements ContextResolver<Genson>
{
private final Genson genson = new Genson.Builder().useRuntimeType(true).useClassMetadata(true).create();
@Override
public Genson getContext(Class<?> arg0)
{
return genson;
}
}
-> JerseyService.java
package com.test;
import javax.ws.rs.*;
import org.codehaus.jackson.*;
@Path("/exampleservice")
public class JerseyService
{
@POST
@Path("somePath")
@Consumer(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Zoo createAnotherZoo(Zoo zoo) throws JsonParseException, JsonMappingException, Exception
{
Zoo newZoo = new Zoo();
Collection<Animal> animals = zoo.getAnimals();
List<Animal> newAnimals = new ArrayList<Animal>();
for (Animal a : animals) {
Dog dog_a = (Dog) a;
Dog dog_b = new Dog();
dog_b.setName(dog_a.getName() + "TEST");
newAnimals.add(dog_b);
}
newZoo.add(newAnimals);
return newZoo;
}
}
输入的JSON如下所示:
{
"animals" : [
{
"name": "Unno"
}
]
}
总而言之,我有一个列表,并且在反序列化对象时尝试使用一种接口实现。
先感谢您。
::::解:::::
如果有人碰到这个:
我按照下面的建议完全删除了genson依赖项。仅使用杰克逊注释,它似乎可以工作。我也从Dog.java的name属性中删除了@JsonProperty。
谢谢 :) :)
最佳答案
我认为您的意思是“在反序列化对象时,我正在尝试使用一种接口实现”。
你的问题
如果这是您的意思,那么简短的答案就是它不能那样工作。
我看到您正在使用Jackson批注,Genson没有看到/使用这些批注(jackson和genson是两个不同的库)。
根据json流(您提供的示例输入),Genson无法知道要绑定到哪个具体类。
一些可能的解决方案是
如果您在两端使用相同的pojos(动物,狗等)和Genson(将数据发布到服务器和服务器的代码),则应使用在两端启用useRuntimeType和useClassMetadata的Genson实例。这将是最简单的解决方案。
类元数据机制在序列化过程中首先将json对象写入具体类型的类名,在反序列化过程中,Genson会使用键@class查找该第一个属性以提取具体的类名。
在您的情况下,如果您能够生成以下形式的json:{“ animals”:{“ @ class”:“ com.test.Dog”,“ name”:“ Unno”}},那么genson会将其发送给正确的类型。请注意,您还可以注册类型的别名,因此您可以只写dog而不是完整的类名。 the documentation中的更多详细信息。
当您具有那些Jackson注释来提供类型提示时,您还可以使用jackson来处理deser(请注意,输入json不适用于此配置,因为它似乎不包含通过注释定义的信息)。在这种情况下,您不应使用Genson来处理带有球衣的序列号,因为jackson和genson都可以完成相同的工作。
关于java - JSON来解决Jersey和Genson的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27197211/