假设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
选择要使用Dog
或Cat
或其他内容反序列化的具体类,entityType
为dog
或{{ 1}}或其他)。由于原因太复杂而无法解释,我无法将类型信息放入JSON输入本身。
因此AIUI使用自定义cat
或类似的东西注释Animal
无法帮助我,因为类型信息不会出现在JSON本身(这就是所有信息,类型解析器将获得)。我打算使用自定义TypeIdResolver
,但据我所知,这不会通过其MessageBodyReader
方法传递来自正文的其他参数值,所以我不知道是什么反序列化。
我错过了什么?如果这种方法失败,我怎么能完成我想要的而不指定特定于动物的端点(导致大量重复的代码以及失去一般性 - 现在我可以添加readValue
的子类和此代码Just Just,这非常好。)
答案 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
类,其中包含你的基本方法,然后构建单独的DogResource
,CatResource
以及你需要的任何其他类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
类。