java – 基于JAX-RS的实现中的简单REST资源版本控制?
REST资源版本控制的最佳做法是将版本信息放入HTTP请求的Accept / Content-Type标头,使URI完好无损.
以下是用于检索系统信息的REST API的示例请求/响应: ==> GET /api/system-info HTTP/1.1 Accept: application/vnd.COMPANY.systeminfo-v1+json <== HTTP/1.1 200 OK Content-Type: application/vnd.COMPANY.systeminfo-v1+json { “session-count”: 19 } 注意在MIME类型中指定的版本. 这是第2版的另一个请求/响应: ==> GET /api/system-info HTTP/1.1 Accept: application/vnd.COMPANY.systeminfo-v2+json <== HTTP/1.1 200 OK Content-Type: application/vnd.COMPANY.systeminfo-v2+json { “uptime”: 234564300,“session-count”: 19 } 有关更多的说明和示例,请参见http://barelyenough.org/blog/tag/rest-versioning/. 在基于Java的JAX-RS实现(如泽西或Apache CXF)中,是否可以轻松实现此方法? 目标是让几个@Resource类具有相同的@Path值,但是根据MIME类型中指定的实际版本来提供请求? 我一直在研究JAX-RS,特别是泽西,并没有发现任何支持.泽西岛没有机会用相同的路径注册两个资源. WebApplicationImpl类的替换需要实现来支持. 你能建议一下吗? 注意:同一资源的多个版本需要同时可用才需要.新版本可能会引入不兼容的更改. 解决方法
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将为应用程序/ vnd.COMPANY.systeminfo json媒体类型选择提供程序.您的MBW将确定实际的媒体类型(再次基于该版本信息),并创建正确的输出格式(再次,也许分派到正确的OSGi加载类). 我不知道MBW是否可以覆盖Content-Type头.如果没有,那么您可以委派较早的过滤器在出路上为您重写该部分. 这有点复杂,但是如果要利用JAX-RS调度,而不是为每种版本的媒体类型创建方法,那么这是一个可行的途径. 编辑响应评论: 是的,本质上,您希望JAX-RS基于Path和Accept类型发送到正确的类. JAX-RS不太可能开箱即用,因为这是一个很好的例子.我没有看过任何JAX-RS实现,但是您可以通过调整基础架构级别之一来完成所需的任务. 可能另一个较少侵入性的选项是使用Apache世界中的一个古老的技巧,只需创建一个基于Accept标头重写路径的过滤器. 所以当系统得到: GET /resource Accept: application/vnd.COMPANY.systeminfo-v1+json 您将其重写为: GET /resource-v1 Accept: application/vnd.COMPANY.systeminfo-v1+json 然后,在您的JAX-RS类中: @Path("resource-v1") @Produces("application/vnd.COMPANY.systeminfo-v1+json") public class ResourceV1 { ... } 所以,您的客户端获得正确的视图,但您的类由JAX-RS正确调度.唯一的其他问题是,如果你的类看,你的类将会看到修改的路径,而不是原始的路径(但如果你喜欢,你的过滤器可以在请求中作为引用填充). 这不是理想的,但它(主要是)是免费的. This是一个现有的过滤器,可以做你想要做的,如果不是,它可能可以作为一个灵感,你自己做. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |