如何通过Repository默认方法在SpringDataRest中暴露自定义端点?
解决方案:通过Spring Data Rest暴露自定义过滤端点
你可以实现需求,不用为每个实体编写控制器,但不能直接将接口中的default方法暴露为查询端点——Spring Data Rest不会识别接口里的default方法作为可暴露的查询操作。下面是两种可行的实现方式:
方式一:自定义Repository实现类(稳定可靠)
这种方式适用于所有Spring Data Rest版本,步骤如下:
1. 定义自定义Repository接口
先创建一个包含过滤方法的自定义接口,分离自定义逻辑:
public interface MyEntityRepositoryCustom { Page<MyEntity> findByFilters(MultiValueMap<String, String> filters, Pageable pageable); }
2. 修改主Repository接口
让主Repository继承自定义接口,并给过滤方法添加@RestResource注解,标记为要暴露的端点:
@Repository @RepositoryRestResource(collectionResourceRel = "myEntity", path = "myEntity") public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity>, MyEntityRepositoryCustom { @RestResource(path = "filter", rel = "filter") Page<MyEntity> findByFilters(MultiValueMap<String, String> filters, Pageable pageable); MyEntity findByName(String name); }
3. 实现自定义逻辑
创建实现类(命名规则:主Repository接口名+Impl),继承SimpleJpaRepository并实现自定义接口:
public class MyEntityRepositoryImpl extends SimpleJpaRepository<MyEntity, Long> implements MyEntityRepositoryCustom { private final EntityManager entityManager; public MyEntityRepositoryImpl(JpaEntityInformation<MyEntity, Long> entityInformation, EntityManager entityManager) { super(entityInformation, entityManager); this.entityManager = entityManager; } @Override public Page<MyEntity> findByFilters(MultiValueMap<String, String> filters, Pageable pageable) { Specification<MyEntity> spec = new GenericSpecification<>(filters.toSingleValueMap(), MyEntity.class); return findAll(spec, pageable); } }
完成后,Spring Data Rest会自动生成端点:/myEntity/search/filter,你可以通过请求参数传递过滤条件,例如:
GET /myEntity/search/filter?filters[name]=张三&filters[age]=25&page=0&size=10
方式二:利用default方法+注解(简化版,视版本支持)
如果你的Spring Data Rest版本较新(比如2.6+),可以直接在default方法上添加注解,无需编写实现类:
@Repository @RepositoryRestResource(collectionResourceRel = "myEntity", path = "myEntity") public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> { @RestResource(path = "filter", rel = "filter") default Page<MyEntity> findByFilters(@RequestParam Map<String, String> filters, Pageable pageable){ Specification<MyEntity> spec = new GenericSpecification<>(filters, MyEntity.class); return findAll(spec, pageable); } MyEntity findByName(String name); }
这种方式更简洁,但要注意部分旧版本Spring Data Rest可能不支持在default方法上识别@RestResource和@RequestParam注解。
内容的提问来源于stack exchange,提问作者Aspiring Dev 23000
相关产品推荐
相关产品推荐

