如何在 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。一个非常简单的修复,但我花了几个星期才弄明白。也许这个答案将来会对其他人有所帮助。