版本化REST API和供应商特定的内容类型
我在这个主题中阅读了很多关于REST API版本的内容: API版本化的最佳实践?
因此,我想使用HTTP-Accept-Header来指示客户端要求的版本。 但是如何在我的应用程序中应用它? 因此,有哪些变化? 编组人员如何知道应该使用哪个版本? 我必须注册我的类型吗?
我所知道的是我必须更改@Produces
-Annotation的内容
@GET @Path("/locations") @Produces("application/vnd.mycompany-v1+xml") Location[] getLocations();
但还有什么必须改变?
您可以使用JAX-RS的Variant
机制。
@GET @Path("/locations/{id}") @Produces(value = {"application/vnd.mycompany-v2+json", // current version "application/vnd.mycompany-v1+json", // old version MediaType.APPLICATION_JSON}) // fallback public Response getLocation(@PathParam("id") Integer id, @Context Request request) { MediaType vndTypeV1 = new MediaType("application", "vnd.mycompany-v1+json"); MediaType vndTypeV2 = new MediaType("application", "vnd.mycompany-v2+json"); Variant variant1 = new Variant(vndTypeV1, null, null); Variant variant2 = new Variant(vndTypeV2, null, null); Variant variantJson = new Variant(MediaType.APPLICATION_JSON_TYPE, null, null); List variants = new ArrayList (); variants.add(variant1); variants.add(variant2); variants.add(variantJson); Variant selectedVariant = request.selectVariant(variants); Location location = someBackendService.getLocation(id); // Manipulate location according to which variant is the selectedVariant. // ... return Response.ok("{}") .header(HttpHeaders.CONTENT_TYPE, selectedVariant.getMediaType()) .build(); }
另请参阅Java EE 6教程 。
编辑
根据所选变体,没有自动编组实体的方法。 这需要一些手动工作。 例如:
String version = extractVersionFromVariant(selectedVariant); if ("v1".equals(version)) { location.setSomeV1Propery("only in v1); } else if ("v2".equals(version)) { location.setSomeV2Propery("only in v2); } return Response.ok(location) .header(HttpHeaders.CONTENT_TYPE, selectVariant.getMediaType()) .build();
如果版本足够不同,我会为每个版本使用JAXB注释类。 然后,每个这样的类只包含那些对该版本有效的属性。 JAX-RS负责将它们编组为JSON。
据我所知,您无法使用JAX-RS根据http标头自动路由到不同的方法。
您可以在您的方法中读取标题(在@context上使用@HeaderParam或HttpHeaders,请参阅此处 )并调用相应的版本
- 使用Apache HttpClient的Java HTTPPost请求
- 在Java中,如何在不生成String对象的情况下从HttpServletRequest标头中提取密码?
- 在Jasperreports中从服务器接收多个不同的Content-Disposition标头
- 未在servlet中的请求中插入自定义标头
- Spring Global CORS配置不起作用,但控制器级配置不起作用
- 使用AWS Java SDK为现有S3对象设置Expires标头
- 使用RestTemplate进行基本身份validation – 编译错误 – 构造函数HttpClient()不可见
- 获取响应获取或发布请求的响应字符集
- 如何在Java中重定向请求时在HTTP标头中传递数据