Spring Data REST如何在线添加嵌入式资源

我正在将Spring Data REST和Hateoas与HAL浏览器结合使用。 这非常有效,但是现在我想用一组特定实体对其关联对象进行JSON转储。 我使用@Projection然后再次卡住了。

仅供参考:正常行为(包含嵌入式和链接等)应保留在新端点(没有嵌入式和链接)之外。

为了进一步说明我的问题/问题:

 class Person { String name; List companies; } class Company { String name; Address address; } class Address { String street; } 

现在我想看到这样的事情:

 { "name": "John", "companies": [ { "name": "Stackoverflow", "address": {"street": "Highway blvd."} }, { "name": "Oracle", "address": {"street": "Main rd."} } ] } 

虽然我得到了这个:

 { "name": "John", "_links": { "self": {"href": "http...."}, "companies": {"href": "http ..."} }, } 

另见: http : //docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts

在我的例子中,我介绍了我遇到的两个困难:列表(公司)和多个级别:人员 – >公司 – >地址。 两者都需要工作(可能有5个级别,其中一些级别有“很多”关系)。

正如您所确定的那样,可接受的内联实体方法是预测。 投影总是内联的,因此一个选项是为每个实体创建投影并将它们组合起来,如下所示:

 @Projection(name = "personProjection", types = Person.class) public interface PersonProjection { String getFirstName(); List getCompanies(); } @Projection(name = "companyProjection", types = Company.class) public interface CompanyProjection { String getName(); AddressProjection getAddress(); } @Projection(name = "addressProjection", types = Address.class) public interface AddressProjection { String getStreet(); } 

一个GET people/1?projection=personProjection仍然会呈现_links元素,但是你会得到你想要的嵌套:

 { "companies" : [ { "address" : { "street" : "123 Fake st", "_links" : { "self" : { "href" : "http://localhost:8080/addresses/1{?projection}", "templated" : true } } }, "name" : "ACME inc.", "_links" : { "self" : { "href" : "http://localhost:8080/companies/1{?projection}", "templated" : true }, "address" : { "href" : "http://localhost:8080/companies/1/address" } } } ], "firstName" : "Will", "_links" : { "self" : { "href" : "http://localhost:8080/people/1" }, "person" : { "href" : "http://localhost:8080/people/1{?projection}", "templated" : true }, "companies" : { "href" : "http://localhost:8080/people/1/companies" } } } 

或者,如果您不需要将CompanyAddress实体公开为其他资源,则可以使用@RepositoryRestResource(exported=false)标记其存储库,并且无论在何处引用它们,它们都将被内联,而无需进行投影。

但最后需要注意的是 – 这个请求在某种程度上与Spring Data REST和Spring HATEOAS的精神作斗争,并引发了大量的,笨拙的查询,遇到了n + 1问题。 请记住,Spring Data REST不是将域模型转换为API的交钥匙解决方案,并且渲染深层对象图(如果这是您的意图)可能是您可能在临时基础上作为自定义控制器端点公开的内容可以彻底控制条件。

在第二个端点中,如果您不需要链接,则必须具有控制器和资源,将数据映射到资源并从控制器返回资源集合

我相信嵌入List或HashMap的最佳方法是将其转换为json字符串并在读取时返回java对象….

这可以很容易地使用

  @Convert(converter = PluginAnalyzerConfigConverter.class) private PluginAnalyzerConfig configuration; //in Entity Class // declare a converter class like this public class PluginAnalyzerConfigConverter implements AttributeConverter { @Override public String convertToDatabaseColumn(PluginAnalyzerConfig config) { Gson parser = new Gson(); return parser.toJson(config, PluginAnalyzerConfig.class); } @Override public PluginAnalyzerConfig convertToEntityAttribute(String source) { Gson parser = new Gson(); return parser.fromJson(source, PluginAnalyzerConfig.class); } } 

如Spring Data with Mysql JSON类型所示

我们在Spring Data DynamoDb中有类似的东西 – 适用于AWS DynamoDB