【发布时间】:2018-09-02 15:45:00
【问题描述】:
我正在使用 Spring Data JPA 来管理 JPA 实体,并且 Spring Data Rest 将存储库导出到 REST API。
我还在构建一个自定义控制器,我想在其中获取实体的 URI(HAL 链接)并通过 CrudRepository 自动将其映射到实体对象。
自定义控制器
@RequestMapping(path = MeLinks.ELEVATE, method = RequestMethod.PUT, consumes = RestMediaTypes.TEXT_URI_LIST_VALUE)
HttpEntity<?> elevate(@RequestBody @Valid CollectionModel<Contact> contact) {
...
}
当尝试使用 Content-Type text/uri-list PUT 像 http://localhost:8080/contacts/1 这样的联系链接时,我可以使用 contact.getLinks() 访问该链接,但不能使用 Contact 对象本身。
Spring Data Rest 是否可以从 URI 中自动推断实体?我知道一个内置的UriToEntityConverter,但我该如何使用它?
编辑
这是一个可行的尝试,但并不能真正优雅地解决问题。
下面的代码初始化一个UriToEntityConverter并将传入的URI转换为域对象。
@Autowired
private ApplicationContext applicationContext;
@Autowired
private MappingContext<?, ?> mappingContext;
@RequestMapping(path = MeLinks.ELEVATE, method = RequestMethod.PUT, consumes = RestMediaTypes.TEXT_URI_LIST_VALUE)
HttpEntity<?> elevate(@RequestBody @Valid CollectionModel<Contact> uris) {
URI uri = URI.create(uris.getLinks().get(0).getHref());
Repositories repositories = new Repositories(applicationContext);
PersistentEntity<?,?> contactPersistentEntity = repositories.getPersistentEntity(Contact.class);
UriToEntityConverter uriToEntityConverter = new UriToEntityConverter(
new PersistentEntities(Collections.singleton(mappingContext)),
new DefaultRepositoryInvokerFactory(repositories),
repositories);
Contact t = (Contact) uriToEntityConverter.convert(uri, TypeDescriptor.valueOf(URI.class), TypeDescriptor.valueOf(Contact.class));
}
您可以想象,从Repository 获取域对象会比上述操作容易得多。假设 URI 使用 ID 作为链接的唯一部分,这也有效。就我而言,我已将其自定义为使用 UUID。所以UriToEntityConverter 的默认行为不起作用。
注意:Resources 类 has been renamed 到 CollectionModel 与 HATEOAS 首次发布。
【问题讨论】:
-
对我有用,但太糟糕了,它不适用于子实体(例如
http://localhost:8080/contacts/1/childEntity)我四处搜索,到目前为止一无所获。 -
@GuiRitter 究竟什么对子实体不起作用?子实体也有存储库还是自定义链接?如果是自定义链接,您是否使用
RepositoryRestController? -
在上面的示例链接中,它尝试将
childEntity解析为Long,就好像我想它是contactid。childEntity确实有一个存储库,但没有自定义链接。 -
啊,我明白了。这可能是因为
UriToEntityConverter仅用于解析根 URI。因此,在您的情况下,要解析的 URI 应该是http://localhost:8080/child_entities/1或类似的。 -
我正在尝试使用您的代码,但是您如何获得 @Autowired private MappingContext, ?> mappingContext;?
标签: spring-mvc spring-data spring-data-rest spring-hateoas