【问题标题】:Implementing Hypermedia in RESTful JAX-RS Apache CXF在 RESTful JAX-RS Apache CXF 中实现超媒体
【发布时间】:2015-04-18 12:57:51
【问题描述】:

我正在使用 Apache CXF 开发的 RESTful 应用程序,我想为它引入超媒体功能。

我们的大部分 jaxrs:serviceBeans 都遵循这个模板:

@GET
@Path("/{exampleId}")
public ExampleJSON get(@PathParam("exampleId") Integer exampleId) {
    ExampleJSON example;
    // Load data from repository here...

    // Add link to self.
    String href = javax.ws.rs.core.Link.fromResource(ExampleService.class).build().getUri().toString();

    // HypermediaLink is a custom object to hold a "href" and "rel" strings
    HypermediaLink linkToSelf = new HypermediaLink();
    linkToSelf.setHref(href + example.getId());
    linkToSelf.setRel("self");

    // Inherited method, just adds a HypermediaLink to a collection in the parent class
    example.addHypermediaLink(linkToSelf);

    // Return JSON compatible object, JACKSON will serialize it nicely.
    return example;
}

这是基本概念。请记住,我出于解释目的简化了此代码;所以,很容易理解。

这段代码运行良好;但我想知道是否有更好的方法来使用 Apache CXF 做到这一点。我对如何增强它有一些想法;但是,它需要一些自定义注释。

我看到了一些使用 Jersey 的示例,但我想坚持使用 Apache CXF。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 我正在考虑是否投票结束您的问题:您的实际问题是什么?你想解决什么问题?你不应该在这里寻求建议。
  • @AndreiI,目前的方法非常冗长。我正在寻找一个图书馆来更好地做这样的事情。 Spring WS 有这样的东西 spring.io/guides/gs/rest-hateoas 。现在,我正在尝试在 Apache CXF 中做类似的事情。
  • CXF 似乎没有任何额外的功能。 JerseyResteasy 都具有处理链接的声明方式(特定于实现)。看着CXF docs,我找不到类似的东西。注释/结合引擎盖过滤器和拦截器是 Jersey 和 Resteasy 使用的。因此,您可能需要创建自己的此类功能实现。
  • 这是一个implementation,我通过快速谷歌搜索找到了。你或许能从中有所收获
  • 谢谢@peeskillet,我以前见过这个。唯一的问题是 jax-rs-hateoas-core 返回一个响应,而我返回一个 POJO(ExampleJSON),后来由 Jackson 序列化。

标签: rest cxf jax-rs


【解决方案1】:

我会利用 JAX-RS 和/或Jackson 的一些特性来实现在序列化级别的幕后添加链接。因此,您不需要为 bean 本身中的链接提供特定字段。

  • 您可以实现自定义MessageBodyWriter 来为您的 POJO 生成不同于默认值的 JSON 有效负载(例如)。所以你可以动态添加链接。

    有关详细信息,请参阅此答案:How to write an XML MessageBodyWriter provider with jersey

  • 如果您使用Jackson 进行序列化,则可以实现自定义序列化程序。请注意,这是通用的,适用于所有受支持的 Jackson 格式。

    下面是示例代码:

    public class LinkBeanSerializer extends JsonSerializer<SomeBean> {
        @Override
        public void serialize(SomeBean bean, JsonGenerator jgen,
                SerializerProvider provider) throws IOException,
                      JsonProcessingException {
            jgen.writeStartObject();
    
            // Fields
            jgen.writeNumberField("id", bean.getId());
            // Things could be generic using reflection
    
            // Link
            String href = javax.ws.rs.core.Link.fromResource(SomeBean.class).build().getUri().toString();
            HypermediaLink linkToSelf = new HypermediaLink();
            linkToSelf.setHref(href + bean.getId());
            linkToSelf.setRel("self");
            jgen.writeObjectField("hypermediaLink", linkToSelf);
    
            jgen.writeEndObject();
        }
    }
    

    请注意,我认为我们可以使这个序列化程序更通用(类似于extends JsonSerializer&lt;Object&gt;

    有关更多详细信息,请参阅此答案:Processing JSON response using JAX-RS(如何在 JAX-RS 中注册自定义序列化程序,...)。

  • 也许实现 WriterInterceptor 可以解决您的问题,但对 bean 有影响,因为您需要拥有字段 hypermediaLink。拦截器可能负责填充该字段。

    有关详细信息,请参阅此答案:Jersey Update Entity Property MessageBodyWriter

IMO 更方便的解决方案是第二种。它是透明的,支持 Jackson 支持的所有格式。

希望对你有帮助, 蒂埃里

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2013-12-18
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多