无法使用 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 HalHandlerInstantiator
和 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());
我使用 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
,如 HalHandlerInstantiator
和 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());