Jackson和JAX-RS:基于@PathParam类型解析抽象类型

时间:2013-03-01 15:10:48

标签: java jackson jax-rs

假设Animal是我项目中的一个抽象类,我有一个REST资源(在JAX-RS服务器上,使用Jackson进行(反)序列化)PUT来操纵动物存储在我的数据库中。它们具有具体类型,REST资源指定请求路径中的类型:

@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{entityType}/{id: \\d+}")
public <T extends Animal> void putAnimal(@PathParam("entityType") String entityType, @PathParam("id") String id, Animal input) throws IOException {
    //...
}

我想使用entityType选择要使用DogCat或其他内容反序列化的具体类,entityTypedog或{{ 1}}或其他)。由于原因太复杂而无法解释,我无法将类型信息放入JSON输入本身。

因此AIUI使用自定义cat或类似的东西注释Animal无法帮助我,因为类型信息不会出现在JSON本身(这就是所有信息,类型解析器将获得)。我打算使用自定义TypeIdResolver,但据我所知,这不会通过其MessageBodyReader方法传递来自正文的其他参数值,所以我不知道是什么反序列化。

我错过了什么?如果这种方法失败,我怎么能完成我想要的而不指定特定于动物的端点(导致大量重复的代码以及失去一般性 - 现在我可以添加readValue的子类和此代码Just Just,这非常好。)

2 个答案:

答案 0 :(得分:4)

JAX-RS规范(5.2.2 URI和URI模板)的以下引用表明您应该能够将UriInfo实例注入自定义MessageBodyReader,并使用其中一个检查请求的URL路径的方法。

  

可以使用@Context注释将UriInfo的实例注入到类字段或方法参数中。 UriInfo提供有关请求URI组件的静态和动态每请求信息。

此处提供的示例显示了接收UriInfo参数的资源方法,但通常也可以将实例注入提供程序(MessageBodyReader)。

通过entityType获取UriInfo路径参数后,您的MessageBodyReader应该能够提供相应的Animal子类。

答案 1 :(得分:0)

考虑到你要做的事情,你最好建立一个AnimalResource类,其中包含你的基本方法,然后构建单独的DogResourceCatResource以及你需要的任何其他类AnimalResource。这将允许您获取Animal的正确子类,从而正确地反序列化输入JSON。

<强>更新 如何实现这一目标的一个例子。您的基本资源如下所示:

public class AnimalResource<T extends Animal>
{
    private final transient AnimalService<T> service;

    public AnimalResource(final AnimalService<T> service)
    {
        this.service = service;
    }

    @Get
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public T getbyId(@PathParam("id") final String id)
    {
        return this.service.findById(id);
    }

    // Other CRUD methods go here
}

然后你的个体动物,假设它们都具有相同的设置,只是:

@Path("/cats")
public class CatResource extends AnimalResource<Cat>
{
    public CatResource(final CatService catService)
    {
        super(catService);
    }
}

对于猫和

@Path("/dogs")
public class DogResource extends AnimalResource<Dog>
{
    public DogResource(final DogService dogService)
    {
        super(dogService);
    }
}

一只狗。他们将从父级继承标准的CRUD方法,并且任何特定于动物的方法仍然可以进入单独的*Resource类。