【问题标题】:Can't get HAL rendering with Spring HATEOAS and Jersey无法使用 Spring HATEOAS 和 Jersey 进行 HAL 渲染
【发布时间】:2016-05-26 14:45:36
【问题描述】:

我使用 Spring Initializr (https://start.spring.io/) 创建了一个只有启动器“Jersey (JAX-RS)”和“HATEOAS”的应用程序。 然后我添加了@EnableHypermediaSupport(type = HAL),但我无法以 HAL 格式正确呈现链接。

我的目标格式:

{
    "name": "Hello",
    "count": 42,
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/foo"
        }
    }
}

我目前得到的是:

{
    "name": "Hello",
    "count": 42,
    "links": [
        {
            "rel": "self",
            "href": "http://localhost:8080/api/foo"
        }
    ]
}

除了initializr生成的类之外,我添加了这个配置

@Configuration
@ApplicationPath("api")
@Component
@EnableHypermediaSupport(type = HAL)
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        registerEndpoints();
    }

    private void registerEndpoints() {
        register(FooResource.class);
    }
}

此资源(端点):

@Component
@Path("foo")
public class FooResource {

    @GET
    @Produces(MediaTypes.HAL_JSON_VALUE)
    public Resource<Foo> getFoo() {

        final Resource<Foo> fooTo = new Resource<>(new Foo("Hello", 42));

        fooTo.add(JaxRsLinkBuilder.linkTo(FooResource.class).withRel("self"));

        return fooTo;
    }
}

还有一个虚拟豆子:

public class Foo {
    private String name;
    private int count;

    public Foo() {
    }

    public Foo(String name, int count) {
        this.name = name;
        this.count = count;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

我也试过添加

@EnableHypermediaSupport(type = HAL)

在应用程序类上的@SpringBootApplication 旁边。

当我

GET localhost:8080/api/foo

我收到内容类型正确的响应

application/hal+json;charset=UTF-8

但格式仍然错误(“链接”属性作为数组而不是“_links”属性作为对象/映射)。

【问题讨论】:

    标签: java spring-boot jersey spring-hateoas


    【解决方案1】:

    只是添加到@zerflagL 的答案,注册Jackson2HalModule,您应该使用ContextResolver,如here 所述。同样在此模块之上,您需要使用ObjectMapper 配置HalHandlerInstantiator。如果你错过了最后一部分,你会得到关于 Jackson 无法实例化序列化器的异常,因为没有默认构造函数。

    @Provider
    public class JacksonContextResolver implements ContextResolver<ObjectMapper> {
    
        private final ObjectMapper mapper = new ObjectMapper();
    
        public JacksonContextResolver() {
            mapper.registerModule(new Jackson2HalModule());
            mapper.setHandlerInstantiator(new HalHandlerInstantiator(
                    new AnnotationRelProvider(), null, null));
        }
    
        @Override
        public ObjectMapper getContext(Class<?> type) {
            return mapper;
        }
    }
    

    然后只需将上下文解析器注册到您的 Jersey ResourceConfig

    register(new JacksonContextResolver());
    

    【讨论】:

    • 非常感谢,这正在工作!我的印象是 JAX-RS 在 Spring HATEOAS 中是一个有效/受支持的选项,因为甚至还有一个 JaxRsLinkBuilder 类。事实证明,JaxRsLinkBuilder 的用处远不如 ControllerLinkBuilder(委婉地说),因为它甚至不支持用于构建链接的 methodOn(),也不支持 JAX-RS 子资源。所以我现在使用自己的 HAL 实现而不是 Spring HATEOAS,并且在此过程中也摆脱了 Spring Web。
    • 我一直想探索this library,但还没有开始。也许你可以看看。
    【解决方案2】:

    Spring HATEOAS 是为与 Spring MVC 一起工作而开发的。与 JSON 序列化/反序列化相关的所有内容都为 Spring MVC 注册,准确地说是MappingJackson2HttpMessageConverter

    如果您想为 Jersey 设置相同的设置,则必须设置 Jackson,以便注册 org.springframework.hateoas.hal.Jackson2HalModule

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多