JSON与Jersey和Genson的对象问题

时间:2014-11-28 23:35:37

标签: java jersey genson

尝试使用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;
    } 
 }

- &GT; 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;
   }
}

- &GT; 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"
     }
    ]
}

总结一下,我有一个List,我在反序列化对象时试图使用其中一个接口实现。

提前谢谢。

:::: SOLUTION :::::

如果有人碰到这个:

我完全删除了genson依赖项,如下所示。只使用杰克逊注释,它似乎工作。我还从Dog.java中的name属性中删除了@JsonProperty。

谢谢:) :))

1 个答案:

答案 0 :(得分:1)

我认为你的意思是&#34;我在反序列化我的对象时试图使用其中一个界面实现。&#34;

您的问题

如果这是你的意思,那么简短的回答是它不能像那样工作。

  1. 我看到你正在使用Jackson注释,Genson没有看到/使用那些注释(jackson和genson是两个不同的库)。

  2. 基于json流(您提供的示例输入)Genson无法知道要绑定哪个具体类


  3. 一些可能的解决方案是

    • 如果您在两端使用相同的pojos(动物,狗等)和Genson(将数据发布到服务器和服务器的代码),则使用启用了useRuntimeType和useClassMetadata的Genson实例两端应该有效。这将是最简单的解决方案。

      • 类序列化过程中的类元数据机制在json对象中作为具体类型的类名的第一个条目写入,在反序列化期间,Genson使用键@class查找第一个属性以提取具体的班级名称。 在你的情况下,如果你能够生成{&#34;动物&#34;:{&#34; @ class&#34;:&#34; com.test.Dog&#34;,&#形式的json 34; name&#34;:&#34; Unno&#34;}},然后genson将它设置为正确的类型。请注意,您还可以为类型注册别名,因此您可以只编写dog而不是完整的类名。 the documentation

      • 中的更多详细信息
      • 正如你有那些Jackson注释给出类型提示,那么你也可以使用jackson来处理deser(请注意,输入json不能用于此配置,因为它似乎不包含通过定义的信息注释)。在这种情况下,你不应该使用Genson来处理带有球衣的ser / de,因为jackson和genson都做同样的工作。