有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法使用Spring HATEOAS和Jersey实现HAL渲染

我使用Spring初始值设定项(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"
        }
    ]
}

除了初始化器生成的类之外,我还添加了这个配置

@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

但仍然是错误的格式(“链接”属性作为数组,而“_链接”属性作为对象/地图)


共 (2) 个答案

  1. # 1 楼答案

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

    如果你想要同样的球衣,你必须设置Jackson,这样org.springframework.hateoas.hal.Jackson2HalModule才能注册

  2. # 2 楼答案

    为了添加@zerflagL的答案,为了注册Jackson2HalModule,应该使用ContextResolver,正如前面提到的here。在这个模块的顶部,您还需要配置^{}ObjectMapper。如果你错过了最后一部分,你会得到关于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());