如何将MongoRepository扩展类中的新方法公开给生成的REST,并包含相同的ALPS/HATEOAS元数据、链接等。
我有一个常用的Spring数据MongoDB存储库:
public interface CollectionRepository extends Repository<Collection, String> {
// Simple queries
Collection findFirstByName(@Param("name") String name);
}现在,我想添加另一个方法,并将它集成到生成的Repository中,以便它与QueryDSL生成的元素一起包含在{存储库}/集合/搜索响应中。
我不得不使用PersistentEntityResourceAssembler和PersistentEntityResource来提供参数,并将响应转换成适当的格式。2)自动生成HATEOAS/ALPS元数据,使父URL在API浏览器中显示带有参数的方法。
这是我的定制控制器。注意,我必须在模板自动装配上指定一个@限定符,因为我有多个数据库,而且它选择了错误的默认数据库。
@Component
@RepositoryRestController
@RequestMapping(value = "{repository}/search")
public class CollectionRepositoryController implements ResourceProcessor<RepositorySearchesResource> {
@Autowired private EntityLinks entityLinks;
@Autowired private PagedResourcesAssembler pagedResourcesAssembler;
@Autowired Repositories repositories;
@Autowired
@Qualifier("mongoTemplateCollections")
private MongoTemplate mongoTemplate;
private final CollectionRepository repository;
@Autowired
public CollectionRepositoryController(CollectionRepository repo) {
repository = repo;
}
@SuppressWarnings("unchecked")
@RequestMapping(value = "findText", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public PagedResources<PersistentEntityResource> findText(
Pageable pageable, @RequestParam(value = "findText", required = false) String findText,
PersistentEntityResourceAssembler resourceAssembler) {
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny(findText);
Query query = TextQuery.queryText(criteria).sortByScore();
List<Collection> collections = mongoTemplate.find(query, Collection.class);
Page<Collection> page = new PageImpl<Collection>(Arrays.asList(new Collection()), pageable, pageable.getOffset());
// What goes below here to convert List<Collections> into PersistentEntityResource ?
PersistentEntity<?, ?> persistentEntity = repositories.getPersistentEntity(Collection.class);
for(Collection collection : collections) {
PersistentEntityResource collectionResource = PersistentEntityResource.build(collection, persistentEntity).
withLink(new Link("/collection/" + collection.getId())).build();
Log.info("collections resource: " + collectionResource);
}
return pagedResourcesAssembler.toResource(page, resourceAssembler);
}
// https://stackoverflow.com/questions/29570962/how-to-add-custom-methods-to-spring-data-rest-jpa-implementation-and-leverage-ha
@Override
public RepositorySearchesResource process(RepositorySearchesResource resource) {
LinkBuilder lb = entityLinks.linkFor(Collection.class, "name");
resource.add(new Link(lb.toString() + "/search/findText{?findText}", "findText"));
return resource;
}
}我也创建了这个程序,但我不知道如何/将它连接到何处:
@Component
public class CollectionResourceAssembler implements ResourceAssembler<Collection, Resource<Collection>> {
@Autowired
EntityLinks entityLinks;
@Override
public Resource<Collection> toResource(Collection collection) {
Resource<Collection> resource = new Resource<Collection>(collection);
final LinkBuilder lb = entityLinks.linkForSingleResource(Collection.class, collection.getId());
resource.add(lb.withSelfRel());
resource.add(lb.slash("answers").withRel("answers"));
// other links
return resource;
}
}我遇到麻烦的地方是“下面是什么”,就像奥利弗建议的那样:
调用存储库并使用可注入到处理程序方法中的PersistentEntityResourceAssembler来生成要返回的PersistentEntityResource。
而且,我真的需要使用ResourceProcessor.process()方法手动设置ALPS/HATEOAS数据吗?还是有一个使其自动化的诀窍?
这是一个无价之宝。我很肯定这里面没有任何东西,所以这说明了如何做到这一点,至少在我需要的手持水平上是这样。这一个也相当接近:为REST Spring HATEOAS控制器定义资源汇编程序,但也假设比我知道的更多。
发布于 2015-07-23 14:12:06
tl;dr
它需要存储库和控制器的自定义实现。
详细信息
我们必须确保我们不会迷失在你在这里提到的所有不同方面。我试着把树枝从下往上解开:
执行MongoDB脚本
正如使用MongoDB执行脚本的参考文档声明的(您已经发现),by MongoTemplate的ScriptOperations提供了该功能。因此,如何使用该API应该是清楚的。
通过Spring数据存储库执行脚本
接下来需要的是通过存储库抽象来执行这些脚本。要避免在这里使用浴缸水将婴儿抛出,请确保我们理解存储库的用途:它模拟聚合根的集合并访问它,而不公开底层的持久性机制。在存储库中公开像ExecutableMongoScript这样的类型会破坏后一个特性。因此,这里正确的方法是为该特定功能定制一个自定义实现,如关于Spring数据仓库的参考文档中所述。
通过REST公开功能
我假设您是在引用Spring的特性,以便在您的问题中公开存储库查询方法的专用资源。Spring数据REST目前只自动公开声明性查询方法,主要原因是很难推理正确的HTTP方法来支持自定义实现,因为我们无法猜出方法内部发生了什么。
推荐的方法是使用自定义控制器公开自定义存储库查询方法,使用适合您的目的的@RequestMapping,调用存储库,并使用可注入到处理程序方法中的PersistentEntityResourceAssembler生成要返回的PersistentEntityResource。
https://stackoverflow.com/questions/31575259
复制相似问题