6

我在这个线程中阅读了很多关于版本控制 REST API 的内容:API 版本控制的最佳实践?

因此,我想使用 HTTP-Accept-Header 来指示客户端要求的版本。但是我怎样才能在我的应用程序中应用它呢?因此做出了哪些改变?编组器如何知道应该使用哪个版本?我必须注册我的类型吗?

我所知道的是我必须更改@Produces-Annotation的内容

@GET
@Path("/locations")
@Produces("application/vnd.mycompany-v1+xml")
Location[] getLocations();

但是还有什么需要改变的?

4

2 回答 2

2

您可以使用VariantJAX-RS 的机制。

@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<Variant> variants = new ArrayList<Variant>();
    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。

于 2012-10-25T08:34:22.993 回答
1

据我所知,您不能使用 JAX-RS 根据 http 标头自动路由到不同的方法。

您可以在您的方法中读取标题(在 @context 上使用 @HeaderParam 或 HttpHeaders 请参阅此处)并调用适当的版本

于 2012-10-23T20:48:22.757 回答