|
此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Data REST 5.0.4! |
配置 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" : "http://localhost:8080/persons/search/findByName"
}
}
}
要更改 rel 值,请在 rel 注解上使用 @RestResource 属性,如下例所示:
@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 名称的能力完全独立于渲染格式。 |
你可以更改仓库的 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" : "http://localhost:8080/people"
},
…
}
}
在前面输出所示的顶层片段中:
-
path = "people"将href中的值从/persons更改为/people。 -
rel = "people"将该链接的名称从persons更改为people。
当你导航到该仓库的 search 资源时,查找方法的 @RestResource 注解已修改了路径,如下所示:
{
"_links" : {
"names" : {
"href" : "http://localhost:8080/people/search/names"
}
}
}
您的仓库定义中的这组注解已导致以下更改:
-
仓库级别注解中的
path = "people"会体现在基础 URI 中,即/people。 -
包含一个查找方法会为您提供
/people/search。 -
path = "names"会创建一个 URI:/people/search/names。 -
rel = "names"将该链接的名称从findByNames更改为names。
隐藏特定的存储库、查询方法或字段
你可能不希望某个仓库、仓库中的某个查询方法,或者实体的某个字段被导出。例如,在 password 对象中隐藏 User 等敏感字段就属于此类情况。要告知导出器不要导出这些项,请使用 @RestResource 注解并将 exported = false 设置为 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;
}
| 投影(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。 |