如何在rest资源spring数据rest中设置export的默认值为false

时间:2017-05-31 21:51:25

标签: java spring rest spring-data

我想使用Spring数据休息的RestResource注释。如您所知,它默认公开所有CRUD方法。但我只需要findAll方法。一种方法是将所有其他方法的导出值设置为false,如下所示:

@RestResource(path="questions")
public interface QuestionRepository extends CRUDRepository<Question,Long> {

@RestResource(exported = false)
void delete(Long id);

@RestResource(exported = false)
void create(Question q);
....
}

但我不喜欢这个。还有其他更简单的方法可以避免这种冶金吗?

4 个答案:

答案 0 :(得分:4)

有一个简单而标准的解决方案,我试过并发现它在spring boot 2.0.2中运行 编写如下所示的配置类和setExposeRepositoryMethodsByDefault(false)并完成它:)

@Component
public class SpringRestConfiguration extends RepositoryRestConfigurerAdapter {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
        config.setExposeRepositoryMethodsByDefault(false);
    }
}

答案 1 :(得分:2)

您可以通过定义实现Repository的中间通用接口来实现此目的,并公开所有使用

注释的PagingAndSortingRepository方法。
@RestController(exported = false).

在该来源的帮助下:https://spring.io/blog/2011/07/27/fine-tuning-spring-data-repositories/,这是我的解决方案:

首先,将RepositoryDe​​tectionStrategy设置为ANNOTATED,以便公开的唯一存储库是那些带注释的@RepositoryRestResource。这可以通过以下方式完成:

@Component
public class SpringRestConfiguration extends 
RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
}
}

定义您的通用Rest存储库。它必须只实现Repository接口,它是空的,而不是CrudRepository或PagingAndSortingRepository,因此您可以精确控制将公开哪些方法,并且公开的方法不依赖于您正在使用的Spring Data版本,或将使用

为了保证非暴露,您必须使用@RestResource(exported = false)注释每个方法。这有点烦人,但为所有人做了一次(你可以复制粘贴,我在CrudRepository和PagingAndSorting中定义所有te方法):

@RepositoryRestResource
@NoRepositoryBean
public interface RestRepositoryMethodExportedFalse<T, ID extends Serializable> 
extends Repository<T, ID> {

/**
 * Returns all entities sorted by the given options.
 * 
 * @param sort
 * @return all entities sorted by the given options
 */
@RestResource(exported = false)
Iterable<T> findAll(Sort sort);

/**
 * Returns a {@link Page} of entities meeting the paging restriction
 * provided in the {@code Pageable} object.
 * 
 * @param pageable
 * @return a page of entities
 */
@RestResource(exported = false)
Page<T> findAll(Pageable pageable);

/**
 * Saves a given entity. Use the returned instance for further operations as
 * the save operation might have changed the entity instance completely.
 * 
 * @param entity
 * @return the saved entity
 */
@RestResource(exported = false)
<S extends T> S save(S entity);

/**
 * Saves all given entities.
 * 
 * @param entities
 * @return the saved entities
 * @throws IllegalArgumentException
 *             in case the given entity is {@literal null}.
 */
@RestResource(exported = false)
<S extends T> Iterable<S> save(Iterable<S> entities);

/**
 * Retrieves an entity by its id.
 * 
 * @param id
 *            must not be {@literal null}.
 * @return the entity with the given id or {@literal null} if none found
 * @throws IllegalArgumentException
 *             if {@code id} is {@literal null}
 */
@RestResource(exported = false)
T findOne(ID id);

/**
 * Returns whether an entity with the given id exists.
 * 
 * @param id
 *            must not be {@literal null}.
 * @return true if an entity with the given id exists, {@literal false}
 *         otherwise
 * @throws IllegalArgumentException
 *             if {@code id} is {@literal null}
 */
@RestResource(exported = false)
boolean exists(ID id);

/**
 * Returns all instances of the type.
 * 
 * @return all entities
 */
@RestResource(exported = false)
Iterable<T> findAll();

/**
 * Returns all instances of the type with the given IDs.
 * 
 * @param ids
 * @return
 */
@RestResource(exported = false)
Iterable<T> findAll(Iterable<ID> ids);

/**
 * Returns the number of entities available.
 * 
 * @return the number of entities
 */
@RestResource(exported = false)
long count();

/**
 * Deletes the entity with the given id.
 * 
 * @param id
 *            must not be {@literal null}.
 * @throws IllegalArgumentException
 *             in case the given {@code id} is {@literal null}
 */
@RestResource(exported = false)
void delete(ID id);

/**
 * Deletes a given entity.
 * 
 * @param entity
 * @throws IllegalArgumentException
 *             in case the given entity is {@literal null}.
 */
@RestResource(exported = false)
void delete(T entity);

/**
 * Deletes the given entities.
 * 
 * @param entities
 * @throws IllegalArgumentException
 *             in case the given {@link Iterable} is {@literal null}.
 */
@RestResource(exported = false)
void delete(Iterable<? extends T> entities);

/**
 * Deletes all entities managed by the repository.
 */
@RestResource(exported = false)
void deleteAll();

}

然后,只需在您的最终存储库中扩展您的自定义中间存储库,并使用您的示例(您自动完成以便快速完成),唯一地覆盖您要公开的方法:

@RestResource(path="questions")
public interface QuestionRepository extends RestRepositoryMethodExportedFalse<Question,Long>{

/**
 * Here is the only method I expose
 */
@RestResource(exported = true)
@Override
Question findOne(Long id);

}

首选将用于设置导出为false的默认值的参数,但在此之前,这是我找到的唯一安全方法。

答案 2 :(得分:0)

您应该为GET /questions请求实现自定义控制器,该控制器仅返回findAll方法的结果,例如:

@RequiredArgsConstructor
@BasePathAwareController
@RequestMapping("/questions")
public class QuestionController {

    private final @NonNull QuestionRepository repository;
    private final @NonNull PagedResourcesAssembler<Question> assembler;
    private final @NonNull EntityLinks links;

    @GetMapping
    ResponseEntity<?> get(Pageable pageable) {
        return ResponseEntity.ok(assembler.toResource(repository.findAll(pageable),
                (ResourceAssembler<Question, ResourceSupport>) question -> 
                    new Resource<>(question,
                    links.linkToSingleResource(question).withSelfRel())));
    }
}

并禁用要导出的QuestionRepository:

@RepositoryRestResource(exported = false)
public interface QuestionRepository extends JpaRepository<Question, Long> {
}

工作example

答案 3 :(得分:0)

进一步介绍对我有帮助的Imran Tahir的答案-谢谢Imran! -您可以通过将ExposeRepositoryMethodsByDefault设置为false来覆盖整个存储库。

getThis()

现在可以从配置文件中设置检测策略。 (在我的情况下为YAML)

@Component
public class SpringRestConfiguration extends RepositoryRestConfigurerAdapter {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
      config.setExposeRepositoryMethodsByDefault(false);
    }
}

然后在存储库中仅将@RestResource添加到您需要启用的(重写)方法中:

spring:
  data:
    rest:
      base-path: /api/base/path
      detection-strategy: annotated