配置 REST URL 路径
您可以配置导出 JPA repository 资源的 URL 路径段。为此,请在类级别或查询方法级别添加注解。
默认情况下,导出器使用域类的名称来暴露您的 CrudRepository
。Spring Data REST 还会应用 Evo Inflector 来将此词复数化。考虑以下 repository 定义
interface PersonRepository extends CrudRepository<Person, Long> {}
上述示例定义的 repository 在 localhost:8080/persons/
处暴露。
要更改 repository 的导出方式,请在类级别添加 @RestResource
注解,如下例所示
@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {}
上述示例定义的 repository 可在 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" : "http://localhost: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" : "http://localhost:8080/persons/search/names"
}
}
}
这些 JSON 片段假设您使用 Spring Data REST 的默认格式 HAL。您可以关闭 HAL,这将导致输出看起来不同。然而,您覆盖 rel 名称的能力完全独立于渲染格式。 |
您可以更改 repository 的 rel
,如下例所示
@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@RestResource(path = "names", rel = "names")
List<Person> findByName(String name);
}
更改 repository 的 rel
会改变顶级名称,如下例输出所示
{
"_links" : {
"people" : {
"href" : "http://localhost:8080/people"
},
…
}
}
在上述输出所示的顶级片段中
-
path = "people"
将href
中的值从/persons
更改为/people
。 -
rel = "people"
将该链接的名称从persons
更改为people
。
当您导航到此 repository 的 search
资源时,finder 方法的 @RestResource
注解已改变了路径,如下所示
{
"_links" : {
"names" : {
"href" : "http://localhost:8080/people/search/names"
}
}
}
您的 repository 定义中的这组注解导致了以下更改
-
Repository 级别注解的
path = "people"
体现在基础 URI 中,显示为/people
。 -
包含 finder 方法为您提供了
/people/search
。 -
path = "names"
创建了一个 URI/people/search/names
。 -
rel = "names"
将该链接的名称从findByNames
更改为names
。
隐藏特定的 Repositories、查询方法或字段
您可能不希望某个 repository、repository 上的某个查询方法或实体的某个字段被导出。例如,隐藏 User
对象上的 password
等敏感字段。要告知导出器不导出这些项,请使用 @RestResource
注解它们并设置 exported = false
。
例如,要跳过导出某个 repository,您可以创建一个类似于以下示例的 repository 定义
@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;
}
Projections 提供了一种方法来改变导出内容,并有效地 绕过这些设置。如果您针对同一个域对象创建了任何 projections,请务必不要导出这些字段。 |
隐藏 Repository CRUD 方法
如果您不想在 CrudRepository
上暴露 save 或 delete 方法,您可以通过覆盖想要关闭的方法并在被覆盖的版本上放置 @RestResource(exported = false)
设置来实现。例如,为了阻止 HTTP 用户调用 CrudRepository
的 delete 方法,请覆盖所有这些方法并在被覆盖的方法上添加注解,如下所示
@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 注解这两个版本。 |