在JSON中禁用超文本应用程序语言(HAL)?

在JSON中禁用超文本应用程序语言(HAL)?,json,rest,spring-data,spring-data-jpa,spring-data-rest,Json,Rest,Spring Data,Spring Data Jpa,Spring Data Rest,在版本2.0.2.0中使用Spring数据REST和JPA 如何在JSON中禁用超文本应用程序语言(HAL) 我已经试过很多东西了,但都没有用。例如,我将Accept和Content-type头设置为“application/json”,而不是“application/hal+json”,但我仍然接收带有超链接的json内容 例如,我想得到如下结果: { "name" : "Foo", "street" : "street Bar", "streetNumber" : 2, "streetLet

在版本2.0.2.0中使用Spring数据REST和JPA

如何在JSON中禁用超文本应用程序语言(HAL)

我已经试过很多东西了,但都没有用。例如,我将Accept和Content-type头设置为“application/json”,而不是“application/hal+json”,但我仍然接收带有超链接的json内容

例如,我想得到如下结果:

{
"name" : "Foo",
"street" : "street Bar",
"streetNumber" : 2,
"streetLetter" : "b",
"postCode" : "D-1253",
"town" : "Munchen",
"country" : "Germany",
"phone" : "+34 4410122000",
"vat" : "000000001",
"employees" : 225,
"sector" : {
     "description" : "Marketing",
     "average profit": 545656665,
     "average employees": 75,
     "average profit per employee": 4556
     }
}
而不是:

{
"name" : "Foo",
"street" : "street Bar",
"streetNumber" : 2,
"streetLetter" : "b",
"postCode" : "D-1253",
"town" : "Munchen",
"country" : "Germany",
"phone" : "+34 4410122000",
"vat" : "000000001",
"employees" : 225,
"_links" : {
     "self" : {
          "href" : "http://localhost:8080/app/companies/1"
     },
     "sector" : {
          "href" : "http://localhost:8080/app/companies/1/sector"
     }
}
}
感谢您的帮助。

(超)媒体类型 Spring Data REST的默认设置使用HAL作为默认超媒体表示格式,因此服务器将为给定的
Accept
头返回以下内容:

  • 无头->
    应用程序/hal+json
    ->hal
  • application/hal+json
    ->
    application/hal+json
    ->hal
  • application/json
    ->
    application/json
    ->HAL(这是默认配置)
  • application/x-spring-data-verbose+json
    ->
    application/x-spring-data-verbose+json
    ->一种spring数据特定格式(使用链接容器的
    links
    ,并使用
    content
    作为集合项的包装器)
如果配置
RepositoryRestConfiguration.setDefaultMediaType(…)
对于非HAL格式,服务器将返回Spring数据特定的JSON格式,除非您明确要求
应用程序/HAL+JSON
。无可否认,配置选项可能有点误导,因此我提出了改进方案。该问题在2014年2.1 RC1(Dijkstra)中得到了解决

请注意,我们实际上需要一种超媒体格式,以便能够表示托管资源之间的关系并启用服务器的可发现性。因此,您无法完全摆脱它。这主要是因为,如果您公开具有双向关系的实体,则很容易使服务器崩溃船舶或组成一个巨大的对象图

内联相关实体 如果您永远不希望将扇区链接到它们并始终将其内联,一个选项是首先将
SectorRepository
作为REST资源导出。您可以通过使用
@RepositoryRestResource(exported=false)
注释存储库接口来实现这一点

要获得在下面示例中发布时返回的表示,请查看SpringDataREST2.1M1中引入的功能。它基本上允许您通过一个简单的界面在资源上创建与默认视图不同的可选视图

您基本上要定义一个接口:

@Projection(name = "foo", types = YourDomainClass.class)
interface Inlined {

  // list all other properties

  Sector getSector();
}
如果您将此接口放入域类的(子)包中,或者通过
RepositoryRestConfiguration.projectionConfiguration()手动注册它
公开
YourDomainClass
的资源将接受一个请求参数
projection
,因此在本例中传入
foo
将呈现您想要的内联表示


提供了有关该功能的更多信息,定义了一个示例投影。

因此您需要两件事:

1) 摆脱
\u链接
字段
2) 包括相关的
扇区
字段

可能的解决方案(适用于我:D)

1) 摆脱
\u链接

为此,请创建以下类:

[... package declaration, imports ...]
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
    public MyRepositoryRestMvcConfiguration(ApplicationContext context, ObjectFactory<ConversionService> conversionService) {
        super(context, conversionService);
    }

    @Bean
    protected LinkCollector linkCollector() {
        return new LinkCollector(persistentEntities(), selfLinkProvider(), associationLinks()) {
            public Links getLinksFor(Object object, List<Link> existingLinks) {
                return new Links();
            }
        };
    }
}
我非常确定(99%,但未测试)您不需要此类来删除下一点(2)显示方式中包含的相关实体的
\u链接

2) 包括相关的
扇区
字段
为此,您可以使用(特别是针对此场景制作的)。因为Spring示例非常有说服力,在这里复制它是愚蠢的,所以我只想指出它:。
但为了记录和方便起见,我将粘贴spring示例的主要部分:

@Projection(name = "inlineAddress", types = { Person.class }) 
interface InlineAddress {
  String getFirstName();
  String getLastName();
  Address getAddress(); 
}
请参见,
types
表示投影类型绑定到的类型。
摘录可以这样使用:

@RepositoryRestResource(excerptProjection = InlineAddress.class)
interface PersonRepository extends CrudRepository<Person, Long> {}
对您来说,
扇区
相当于
地址

最终注释

返回数组时,
\u links
字段不会被删除(这样做太麻烦);最后你会有这样的东西:

{
    "_embedded" : {
        "persons" : [ {person1}, {person2}, ..., {personN} ]
    },
    "_links" : {
        e.g. first, next, last, self, profile
    },
    "page" : {
      "size" : 1,
      "totalElements" : 10,
      "totalPages" : 10,
      "number" : 0
    }
}
正如你所见,即使我们删除了
\u链接
,这仍然是不够的;人们可能还希望将
\u embedded
替换为
persons
,这将导致可维护性较差的代码(过多的spring侵入式覆盖)。但是如果你真的想要这些,他应该开始检查
RepositoryRestMvcConfiguration
RepositoryEntityController.getCollectionResource

Spring正在发展,因此我觉得有必要指出,这至少适用于:

spring-data-rest-webmvc 3.1.3.RELEASE
或者,如果您预选了spring引导版本:

spring-boot-starter-parent 2.1.1.RELEASE

这可能是由于反射API以不同的顺序返回方法造成的。但是,投影界面是开放的,可以通过Jackson注释进行自定义,因此
@JsonPropertyOrder
应该允许您根据需要自定义内容。我确认:@JsonPropertyOrder工作正常。非常感谢您的帮助。可以完全禁用hal吗?我只想检索带有实体ID的JSON。你不觉得这有点傻吗?如果我有100个模型,我需要创建100个投影。我不这么认为。我正在寻找一个配置标志,让我只发送Json或HalJson,而不是HalJson。SDR的超媒体特性的问题是简单的RESTAPI(即richardson成熟度模型的2级)是主流的,并经过生产验证。超媒体API的可用性(3级)仍有待评判。将SDR与超媒体捆绑在一起似乎使其处于实验状态,这使得它很难销售给任何需要生产准备API的人——或者我遗漏了什么?我喜欢你的答案,它提供了一个很好的图图
spring-data-rest-webmvc 3.1.3.RELEASE
spring-boot-starter-parent 2.1.1.RELEASE