java - 实现 Spring Data 存储库的自定义方法并通过 REST 公开它们

标签 java spring rest jpa spring-data

我正在尝试向我的 Spring Data 存储库 PersonRepository 添加自定义方法,如 1.3 Custom implementations for Spring Data repositories 中所述并通过 REST 公开这些方法。初始代码来自 Accessing JPA Data with REST示例,这里是添加/修改类的代码:

interface PersonRepositoryCustom {
  List<Person> findByFistName(String name);
}

class PersonRepositoryImpl implements PersonRepositoryCustom, InitializingBean {
  @Override
  public void afterPropertiesSet() throws Exception {
    // initialization here
  }
  @Override
  public List<Person> findByFistName(String name) {
    // find the list of persons with the given firstname
  }
}

@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
  List<Person> findByLastName(@Param("name") String name);  
}

当我运行应用程序并访问 http://localhost:8080/portfolio/search/ 时,我得到以下响应正文:

{
  "_links" : {
    "findByLastName" : {
      "href" : "http://localhost:8080/people/search/findByLastName{?name}",
      "templated" : true
     }
  }
}

为什么findByFirstName即使在PersonRepository接口(interface)中可用也不暴露?

另外,有没有办法动态/以编程方式添加要通过 REST 公开的存储库?

最佳答案

两天后,我就这样解决了。

自定义存储库接口(interface):

public interface PersonRepositoryCustom {
    Page<Person> customFind(String param1, String param2, Pageable pageable);
}

自定义存储库实现

public class PersonRepositoryImpl implements PersonRepositoryCustom{

    @Override
    public Page<Person> customFind(String param1, String param2, Pageable pageable) {
        // custom query by mongo template, entity manager...
    }
}

Spring 数据存储库:

@RepositoryRestResource(collectionResourceRel = "person", path = "person")
public interface PersonRepository extends MongoRepository<Person, String>, PersonRepositoryCustom {
    Page<Person> findByName(@Param("name") String name, Pageable pageable);
}

Bean 资源表示

public class PersonResource extends org.springframework.hateoas.Resource<Person>{

    public PersonResource(Person content, Iterable<Link> links) {
        super(content, links);
    }
}

资源汇编器

@Component
public class PersonResourceAssembler extends ResourceAssemblerSupport<Person, PersonResource> {

    @Autowired
    RepositoryEntityLinks repositoryEntityLinks;

    public PersonResourceAssembler() {
        super(PersonCustomSearchController.class, PersonResource.class);
    }

    @Override
    public PersonResource toResource(Person person) {
        Link personLink = repositoryEntityLinks.linkToSingleResource(Person.class, person.getId());
        Link selfLink = new Link(personLink.getHref(), Link.REL_SELF);
        return new PersonResource(person, Arrays.asList(selfLink, personLink));
    }

}

自定义 Spring MVC Controller

@BasePathAwareController
@RequestMapping("person/search")
public class PersonCustomSearchController implements ResourceProcessor<RepositorySearchesResource> {

    @Autowired
    PersonRepository personRepository;

    @Autowired
    PersonResourceAssembler personResourceAssembler;

    @Autowired
    private PagedResourcesAssembler<Person> pagedResourcesAssembler;

    @RequestMapping(value="customFind", method=RequestMethod.GET)
    public ResponseEntity<PagedResources> customFind(@RequestParam String param1, @RequestParam String param2, @PageableDefault Pageable pageable) {
        Page personPage = personRepository.customFind(param1, param2, pageable);
        PagedResources adminPagedResources = pagedResourcesAssembler.toResource(personPage, personResourceAssembler);

        if (personPage.getContent()==null || personPage.getContent().isEmpty()){
            EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
            EmbeddedWrapper wrapper = wrappers.emptyCollectionOf(Person.class);
            List<EmbeddedWrapper> embedded = Collections.singletonList(wrapper);
            adminPagedResources = new PagedResources(embedded, adminPagedResources.getMetadata(), adminPagedResources.getLinks());
        }

        return new ResponseEntity<PagedResources>(adminPagedResources, HttpStatus.OK);
    }

    @Override
    public RepositorySearchesResource process(RepositorySearchesResource repositorySearchesResource) {
        final String search = repositorySearchesResource.getId().getHref();
        final Link customLink = new Link(search + "/customFind{?param1,param2,page,size,sort}").withRel("customFind");
        repositorySearchesResource.add(customLink);
        return repositorySearchesResource;
    }

}

关于java - 实现 Spring Data 存储库的自定义方法并通过 REST 公开它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25201306/

相关文章:

java - 使用 Java 准备语句的 Sybase 查询不起作用

由于 Autowiring JavaMailSender,SpringBoot 应用程序启动失败 - 版本 2.0.0-snapshot

php - Magento REST API 示例代码 404s

java - 如何设置 vaadin 布局的宽度并仍然让内部组件占用所需的空间?

java - 相互左递归 ANTLR 4

java - Spring JAXB - 使用模式验证解码 XML 文档

java - 如何捕获 org.springframework.dao.DataIntegrityViolationException : Could not execute JDBC batch update

java - Spring 集成: start JPA polling only when all the results of last polling has been processed

rest - 如何使用 REST API 在 SalesForce 中获取潜在客户详细信息?

java - 如何在没有 xml 的 Spring MVC 中启用 REST gzip 压缩?