如何在 spring 应用程序中更改 Hateoas 输出格式?
How to change Hateoas output format in spring application?
我目前正在开发一个 spring 应用程序,它提供了一个 REST 接口,可以使用该接口对各种实体执行 CRUD 操作。这些实体存储在存储库中,因此 REST 接口的主要部分由 spring 自动生成。当我对此类实体类型(例如 /devices
)执行 GET 请求时,结果如下所示:
{
"_embedded":{
"devices":[
{
"macAddress": "...",
"ipAddress": "...",
"name": "Device_1",
"id":"5c866db2f8ea1203bc3518e8",
"_links":{
"self":{
...
},
"device":{
...
}
}, ...
]
},
"_links":{
...
},
"page":{
"size":20,
"totalElements":11,
"totalPages":1,
"number":0
}
}
现在我需要手动实现一个类似的接口,因为需要额外的检查。为此,我使用了 spring-hateoas 功能。但是,我无法实现与 spring 自动生成的输出结构相同的输出结构。我的控制器 class 中的相应代码(用 RestController
注释)如下所示:
@GetMapping("/devices")
public Resources<Device> getDevices() {
List<Device> deviceList = getDeviceListFromRepository();
Link selfRelLink = ControllerLinkBuilder.linkTo(
ControllerLinkBuilder.methodOn(RestDeviceController.class)
.getDevices())
.withSelfRel();
Resources<Device> resources = new Resources<>(deviceList);
resources.add(selfRelLink);
return resources;
}
配置(摘录)如下所示:
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
public class WebServletConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware {
...
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer c) {
c.defaultContentType(MediaTypes.HAL_JSON);
}
...
}
但是,这是一个请求的输出:
{
"links":[
{
"rel":"self",
"href":"..."
}
],
"content":[
{
"id":"5c866db2f8ea1203bc3518e8",
"name":"Device_1",
"macAddress": "...",
"ipAddress":"...",
}
]
}
如您所见,没有 _embedded
键而是 content
键,而 links
键缺少前导下划线。这些是我对这个输出的主要问题,与上面的输出相比更详细的差异对我来说并不那么重要。我想统一我的应用程序生成的输出,但我无法实现spring自动生成的映射的输出格式。我还尝试将 resources
对象包装到另一个 resource
对象中(如 return new Resource<...>(resources)
),但效果不佳。
关于我在这里做错了什么,你有什么提示吗?我对 Spring & Co 很陌生,所以如果您需要有关某件事的更多信息,请告诉我。非常感谢任何帮助。提前致谢!
终于找到了解决方法:问题中的奇怪输出格式是由于客户端发送的accept header application/json
而产生的。添加后
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true);
configurer.defaultContentType(MediaTypes.HAL_JSON);
}
到 class WebServletConfiguration
扩展 WebMvcConfigurerAdapter
一切都按预期工作,输出格式现在是 HAL-like。一个非常简单的修复,但我花了几个星期才弄明白。也许这个答案将来会对其他人有所帮助。
我目前正在开发一个 spring 应用程序,它提供了一个 REST 接口,可以使用该接口对各种实体执行 CRUD 操作。这些实体存储在存储库中,因此 REST 接口的主要部分由 spring 自动生成。当我对此类实体类型(例如 /devices
)执行 GET 请求时,结果如下所示:
{
"_embedded":{
"devices":[
{
"macAddress": "...",
"ipAddress": "...",
"name": "Device_1",
"id":"5c866db2f8ea1203bc3518e8",
"_links":{
"self":{
...
},
"device":{
...
}
}, ...
]
},
"_links":{
...
},
"page":{
"size":20,
"totalElements":11,
"totalPages":1,
"number":0
}
}
现在我需要手动实现一个类似的接口,因为需要额外的检查。为此,我使用了 spring-hateoas 功能。但是,我无法实现与 spring 自动生成的输出结构相同的输出结构。我的控制器 class 中的相应代码(用 RestController
注释)如下所示:
@GetMapping("/devices")
public Resources<Device> getDevices() {
List<Device> deviceList = getDeviceListFromRepository();
Link selfRelLink = ControllerLinkBuilder.linkTo(
ControllerLinkBuilder.methodOn(RestDeviceController.class)
.getDevices())
.withSelfRel();
Resources<Device> resources = new Resources<>(deviceList);
resources.add(selfRelLink);
return resources;
}
配置(摘录)如下所示:
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
public class WebServletConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware {
...
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer c) {
c.defaultContentType(MediaTypes.HAL_JSON);
}
...
}
但是,这是一个请求的输出:
{
"links":[
{
"rel":"self",
"href":"..."
}
],
"content":[
{
"id":"5c866db2f8ea1203bc3518e8",
"name":"Device_1",
"macAddress": "...",
"ipAddress":"...",
}
]
}
如您所见,没有 _embedded
键而是 content
键,而 links
键缺少前导下划线。这些是我对这个输出的主要问题,与上面的输出相比更详细的差异对我来说并不那么重要。我想统一我的应用程序生成的输出,但我无法实现spring自动生成的映射的输出格式。我还尝试将 resources
对象包装到另一个 resource
对象中(如 return new Resource<...>(resources)
),但效果不佳。
关于我在这里做错了什么,你有什么提示吗?我对 Spring & Co 很陌生,所以如果您需要有关某件事的更多信息,请告诉我。非常感谢任何帮助。提前致谢!
终于找到了解决方法:问题中的奇怪输出格式是由于客户端发送的accept header application/json
而产生的。添加后
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true);
configurer.defaultContentType(MediaTypes.HAL_JSON);
}
到 class WebServletConfiguration
扩展 WebMvcConfigurerAdapter
一切都按预期工作,输出格式现在是 HAL-like。一个非常简单的修复,但我花了几个星期才弄明白。也许这个答案将来会对其他人有所帮助。