如何向Spring Data Rest JPA实现添加自定义方法并利用HATEOS支持?

时间:2015-04-10 21:28:08

标签: spring-data-jpa spring-data-rest spring-hateoas

我有一个Spring Data Rest Repository控制器,它使用JPA进行查询实现,我需要添加一些使用JPA支持的标准queryByExample方法无法完成的自定义查询方法。我创建了一个具有必要方法的Impl类,但我不能让它被识别。我看到我可以使用标准的Spring MVC控制器,但我希望有一个统一的API,基本上我真正想要的是实现我自己的自定义/搜索方法。

即使使用自定义控制器,问题仍然是不再提供HAL链接和其他相关项目。

春天的人们可以花一些时间让别人记录如何做一些这些更高级的东西吗?我猜测,有时必须实施自己的搜索方法是相当普遍的,并且花时间来明确如何做到这一点。

3 个答案:

答案 0 :(得分:10)

一个简单的实现可能如下所示:

@BasePathAwareController
class CustomInvocationsController implements ResourceProcessor<RepositorySearchesResource> {

  private final YourRepository repository;

  public CustomInvocationsController(YourRepository repository) {
    this.repository = repository;
  }

  @RequestMapping(…)
  ResponseEntity<?> handleRequest(PersistentEntityResourceAssembler assembler)

    // invoke repository
    // Use assembler to build a representation
    // return ResponseEntity
  }

  @Override
  public RepositorySearchesResource process(RepositorySearchesResource resource) {
    // add Link to point to the custom handler method
  }
}

有几点需要注意:

  • 使用@BasePathAwareController而不是普通的@Controller确保无论您将处理程序方法映射到何处,它都会考虑您在Spring Data REST上配置的基本路径。
  • 在请求映射中,使用您在Spring MVC中已知的所有内容,选择适当的HTTP方法。
  • PersistentEntityResourceAssembler基本上抽象在PersistentEntityResource内设置表示模型,以便对关联等的Spring Data REST特定处理启动(关联成为链接等。
  • 实施ResourceProcessor以后处理RepositorySearchesResource,该资源会为资源呈现所有搜索而返回。目前,无法确定该资源所呈现的域类型。我提交并修复了DATAREST-515以改善这一点。

答案 1 :(得分:4)

好的,根据目前提供的信息,我认为有些工作是合理的。到目前为止,我一直在找人来验证我的理论。

目标是能够为SDR已经提供的方法实现其他自定义方法。这是因为我需要实现额外的逻辑,这些逻辑不能表达为简单的Spring Data Repository查询方法(findByXXX方法)。在这种情况下,我希望查询其他数据源,如Solr,以及在返回数据之前提供数据的自定义操作。

我已根据@oliver的建议实现了一个控制器,如下所示:

@BasePathAwareController
@RequestMapping(value = "/persons/search")
public class PersonController implements ResourceProcessor<RepositorySearchesResource>, ResourceAssembler<Person, Resource<Person>> {

    @Autowired
    private PersonRepository repository;

    @Autowired
    private EntityLinks entityLinks;

    @RequestMapping(value = "/lookup", method = RequestMethod.GET)
    public ResponseEntity<Resource<Person>> lookup(@RequestParam("name") String name)
    {
        try
        {
          Resource<Person> resource = toResource(repository.lookup(name));
          return new ResponseEntity<Resource<Person>>(resource, HttpStatus.OK);
        }
        catch (PersonNotFoundException nfe)
        {
            return new ResponseEntity<Resource<Person>>(HttpStatus.OK);
        }
    }

    @Override
    public RepositorySearchesResource process(RepositorySearchesResource resource) {

        LinkBuilder lb = entityLinks.linkFor(Person.class, "name");
        resource.add(new Link(lb.toString() + "/search/lookup{?name}", "lookup"));
        return resource;
    }

    @Override
    public Resource<Person> toResource(Person person) {
        Resource<IpMaster> resource = new Resource<Person>(person);

        return resource;
    }

这会产生&#34;查找&#34;被视为模板的方法,在/persons/search上执行查询时列出,以及Repository中定义的其他搜索方法。它没有使用建议的PersistentEntityResourceAssembler。我想我宁愿使用它,但是我对如何注入它有点困惑,以及对提交的bug的评论意味着什么。

答案 2 :(得分:0)

请参阅最新文档,因为SDR的最新版本有更多详细信息,并且使其更容易一些。关键是使用@RepositoryRestController注释能够在/search端点下添加其他方法,或者如果要将端点添加到url命名空间的其他部分,则可以添加@BasePathAwareController注释。然后将PersistentEntityResourceAssembler作为参数包含在控制器方法中,如果要返回实体对象,则使用它来生成HAL输出。