JAX-RS通过Accept标头将其分配给以@Produces注释的方法。因此,如果您希望JAX-
RS进行调度,则需要利用此机制。如果没有任何额外的工作,则必须为要支持的每种媒体类型创建一个方法(和提供程序)。
没有什么可以阻止您使用几种基于媒体类型的方法来全部调用一个通用方法来完成这项工作的,但是每次添加新的媒体类型时,您都必须对其进行更新并添加代码。
一种想法是添加一个过滤器,以“规范化”您的Accept标头,专门用于分派。也就是说,可能是您:
Accept: application/vnd.COMPANY.systeminfo-v1+json
并将其转换为:
Accept: application/vnd.COMPANY.systeminfo+json
同时,您提取版本信息以供以后使用(也许在请求中,或者在其他临时机制中)。
然后,JAX-RS将分派到处理“ application / vnd.COMPANY.systeminfo + json”的单个方法。
然后,该方法使用“带外”版本控制信息来处理处理中的详细信息(例如,选择适当的类以通过OSGi加载)。
接下来,然后使用适当的MessageBodyWriter创建一个Provider。JAX-RS将为application /
vnd.COMPANY.systeminfo +
json媒体类型选择提供程序。由MBW决定实际的媒体类型(再次基于该版本信息)并创建正确的输出格式(同样,也许分派到正确的OSGi加载类)。
我不知道MBW是否可以覆盖Content-Type标头。如果没有,那么您可以委托较早的过滤器在出路时为您重写该部分。
这有点令人费解,但是如果您想利用JAX-RS调度,而不是为每种类型的媒体类型创建方法,那么这是可行的方法。
编辑以回应评论:
是的,从本质上讲,您希望JAX-RS基于Path和Accept类型将其分派到适当的类。JAX-
RS不太可能开箱即用,因为这是一个边缘情况。我没有看过任何JAX-RS的实现,但是您可以通过在基础结构级别上调整其中一个来完成您想要的事情。
可能的另一种侵入性较小的方法是使用来自Apache世界的古老技巧,并简单地创建一个过滤器,该过滤器根据Accept标头重写您的路径。
因此,当系统得到:
GET /resourceAccept: application/vnd.COMPANY.systeminfo-v1+json
您将其重写为:
GET /resource-v1Accept: application/vnd.COMPANY.systeminfo-v1+json
然后,在您的JAX-RS类中:
@Path("resource-v1")@Produces("application/vnd.COMPANY.systeminfo-v1+json")public class ResourceV1 { ...}因此,您的客户端获得了正确的视图,但是JAX-
RS正确地调度了您的类。唯一的另一个问题是,如果您的类看的话,它们将看到修改后的Path,而不是原始路径(但是,如果您愿意,您的过滤器可以将该请求中的内容作为参考)。
它不是理想的,但是(大部分)是免费的。
这是一个现有的过滤器,可能会做您想做的事情,如果没有,它可能会启发您自己做。



