无法使用 Spring HATEOAS 和 Jersey 进行 HAL 渲染

Can't get HAL rendering with Spring HATEOAS and Jersey

我使用 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生成的classes,我还添加了这个配置

@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;
    }
}

和一个虚拟 bean:

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)

应用程序 class.

上的 @SpringBootApplication 旁边

当我

GET localhost:8080/api/foo

我收到内容类型正确的回复

application/hal+json;charset=UTF-8

但格式仍然错误("link" 属性 as array instaed of "_links" 属性 as object/map).

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

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

只是添加@zerflagL 的答案,要注册 Jackson2HalModule,您应该使用 ContextResolver,如 . Also on top of this module, you need to configure the HalHandlerInstantiatorObjectMapper 所述。如果你错过了最后一部分,你会得到关于 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());