配置 REST URL 路径
您可以配置 JPA 存储库资源导出的 URL 路径段。为此,在类级别或查询方法级别添加注解。
默认情况下,导出器使用领域类的名称公开您的 CrudRepository。Spring Data REST 还会应用 Evo Inflector 将该词复数化。请看以下存储库定义
interface PersonRepository extends CrudRepository<Person, Long> {}
上述示例定义的存储库在 localhost:8080/persons/ 上公开。
要更改存储库的导出方式,请在类级别添加 @RestResource 注解,如下例所示
@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {}
上述示例定义的存储库可通过 localhost:8080/people/ 访问。
如果您定义了查询方法,它们也默认通过其名称公开,如下例所示
interface PersonRepository extends CrudRepository<Person, Long> {
List<Person> findByName(String name);
}
上述示例中的方法在 localhost:8080/persons/search/findByName 上公开。
所有查询方法资源都在 search 资源下公开。 |
要更改此查询方法公开的 URL 段,您可以再次使用 @RestResource 注解,如下例所示
@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@RestResource(path = "names")
List<Person> findByName(String name);
}
现在,上述示例中的查询方法在 localhost:8080/people/search/names 上公开。
处理 rel 属性
由于这些资源都是可发现的,您还可以影响导出器发送的链接中 rel 属性的显示方式。
例如,在默认配置中,如果您向 localhost:8080/persons/search 发送请求以找出公开了哪些查询方法,您会得到一个类似的链接列表
{
"_links" : {
"findByName" : {
"href" : "https://:8080/persons/search/findByName"
}
}
}
要更改 rel 值,请使用 @RestResource 注解上的 rel 属性,如下例所示
@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@RestResource(path = "names", rel = "names")
List<Person> findByName(String name);
}
上述示例会产生以下链接值
{
"_links" : {
"names" : {
"href" : "https://:8080/persons/search/names"
}
}
}
这些 JSON 片段假设您使用 Spring Data REST 的默认 HAL 格式。您可以关闭 HAL,这将导致输出看起来不同。但是,您覆盖 rel 名称的能力完全独立于渲染格式。 |
您可以更改存储库的 rel,如下例所示
@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@RestResource(path = "names", rel = "names")
List<Person> findByName(String name);
}
更改存储库的 rel 会更改顶级名称,如下例输出所示
{
"_links" : {
"people" : {
"href" : "https://:8080/people"
},
…
}
}
在上述输出所示的顶级片段中
-
path = "people"将href中的值从/persons更改为/people。 -
rel = "people"将该链接的名称从persons更改为people。
当您导航到此存储库的 search 资源时,查找方法的 @RestResource 注解已更改了路径,如下所示
{
"_links" : {
"names" : {
"href" : "https://:8080/people/search/names"
}
}
}
存储库定义中的这组注解导致了以下更改
-
存储库级别注解的
path = "people"反映在带有/people的基本 URI 中。 -
包含查找方法为您提供了
/people/search。 -
path = "names"创建了/people/search/names的 URI。 -
rel = "names"将该链接的名称从findByNames更改为names。
隐藏某些存储库、查询方法或字段
您可能不希望某些存储库、存储库上的查询方法或实体字段被导出。示例包括隐藏 User 对象上的 password 等字段和类似敏感数据。要告诉导出器不导出这些项目,请使用 @RestResource 对其进行注解并设置 exported = false。
例如,要跳过导出存储库,您可以创建一个类似于以下示例的存储库定义
@RepositoryRestResource(exported = false)
interface PersonRepository extends CrudRepository<Person, Long> {}
要跳过导出查询方法,您可以对查询方法使用 @RestResource(exported = false) 进行注解,如下所示
@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@RestResource(exported = false)
List<Person> findByName(String name);
}
同样,要跳过导出字段,您可以对字段使用 @RestResource(exported = false) 进行注解,如下所示
@Entity
public class Person {
@Id @GeneratedValue private Long id;
@OneToMany
@RestResource(exported = false)
private Map<String, Profile> profiles;
}
| 投影提供了更改导出内容并有效绕过这些设置的方法。如果您针对同一领域对象创建任何投影,请务必不要导出字段。 |
隐藏存储库 CRUD 方法
如果您不想在 CrudRepository 上公开保存或删除方法,您可以通过重写要关闭的方法并将注解放在重写版本上来使用 @RestResource(exported = false) 设置。例如,为了防止 HTTP 用户调用 CrudRepository 的删除方法,请重写所有这些方法并将注解添加到重写方法中,如下所示
@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@Override
@RestResource(exported = false)
void delete(Long id);
@Override
@RestResource(exported = false)
void delete(Person entity);
}
重要的是您要重写两个 delete 方法。为了提高运行时性能,导出器目前使用一种有些幼稚的算法来确定要使用哪个 CRUD 方法。您目前无法关闭接受 ID 的 delete 版本,但可以导出接受实体实例的版本。暂时,您可以选择导出或不导出 delete 方法。如果您想关闭它们,请记住必须使用 exported = false 注解这两个版本。 |