使用Spring HATEOAS和Jersey无法获得HAL渲染

时间:2016-02-15 15:53:25

标签: java spring-boot jersey spring-hateoas

我使用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

但仍然是错误的格式(“link”属性作为“_links”属性的数组安装为对象/地图)。

2 个答案:

答案 0 :(得分:4)

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

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

然后只需使用泽西ResourceConfig

注册上下文解析器
register(new JacksonContextResolver());

答案 1 :(得分:3)

Spring HATEOAS开发用于Spring MVC。与JSON序列化/解除相关的所有内容都是为Spring MVC注册的,MappingJackson2HttpMessageConverter是准确的。

如果你想为泽西岛做同样的事情,你必须设置杰克逊,以便org.springframework.hateoas.hal.Jackson2HalModule注册。