共计 7271 个字符,预计需要花费 19 分钟才能阅读完成。
原题目:Spring 认证中国教育管理中心 -Spring Data Couchbase 教程七(Spring 中国教育管理中心)
Spring Data Couchbase 教程七
4.8.2. 网络反对
反对存储库编程模型的 Spring Data 模块附带各种 Web 反对。Web 相干组件要求 Spring MVC JAR 位于类门路中。其中一些甚至提供与 Spring HATEOAS 的集成。通常,通过应用 @
EnableSpringDataWebSupportJavaConfig 配置类中的正文来启用集成反对,如以下示例所示:
示例 66. 启用 Spring Data web 反对
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}
该 @
EnableSpringDataWebSupport 批注注册几个组件。咱们将在本节前面探讨这些内容。它还检测类门路上的 Spring HATEOAS 并为其注册集成组件(如果存在)。
或者,如果您应用 XML 配置,则注册为 Spring
beanSpringDataWebConfiguration 或注册 HateoasAwareSpringDataWebConfiguration 为 Spring beans,如以下示例所示 (for SpringDataWebConfiguration):
示例 67. 在 XML 中启用 Spring Data Web 反对
<bean class=”org.springframework.data.web.config.SpringDataWebConfiguration” />
<!– If you use Spring HATEOAS, register this one instead of the former –>
<bean class=”org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration” />
根本网络反对
上一节中显示的配置注册了一些根本组件:
A 应用 DomainClassConverterClass 让 Spring MVC 从申请参数或门路变量中解析存储库治理的域类的实例。
HandlerMethodArgumentResolver 让 Spring MVC 从申请参数解析 Pageable 和 Sort 实例的实现。
Jackson 模块用于反 / 序列化 Point 和 等类型 Distance,或存储特定类型,具体取决于应用的 Spring 数据模块。
应用 DomainClassConverter 类
本 DomainClassConverter 类让你在 Spring MVC 中的控制器办法签名应用域类型间接使您不用手动通过资源库查找的状况下,如下例所示:
示例 68. 在办法签名中应用域类型的 Spring MVC 控制器
@Controller
@RequestMapping(“/users”)
class UserController {
@RequestMapping(“/{id}”)
String showUserForm(@PathVariable(“id”) User user, Model model) {
model.addAttribute("user", user);
return "userForm";
}
}
该办法 User 间接接管实例,无需进一步查找。实例能够通过让 Spring MVCid 先将 path 变量转换为域类的类型,最终通过调用 findById(…)为域类型注册的 repository 实例来拜访实例。
目前,必须施行存储库才有 CrudRepository 资格被发现进行转换。
用于分页和排序的 HandlerMethodArgumentResolvers
上一节中显示的配置片段还注册了
aPageableHandlerMethodArgumentResolver 以及 SortHandlerMethodArgumentResolver. 注册启用 Pageable 并 Sort 作为无效的控制器办法参数,如以下示例所示:
示例 69. 应用 Pageable 作为控制器办法参数
@Controller
@RequestMapping(“/users”)
class UserController {
private final UserRepository repository;
UserController(UserRepository repository) {
this.repository = repository;
}
@RequestMapping
String showUsers(Model model, Pageable pageable) {
model.addAttribute("users", repository.findAll(pageable));
return "users";
}
}
后面的办法签名导致 Spring MVC 尝试 Pageable 应用以下默认配置从申请参数中派生一个实例:
Spring Data Couchbase 教程七
要自定义此行为,请别离注册一个实现
PageableHandlerMethodArgumentResolverCustomizer 接口或 SortHandlerMethodArgumentResolverCustomizer 接口的 bean。它的 customize() 办法被调用,让您更改设置,如以下示例所示:
@Bean SortHandlerMethodArgumentResolverCustomizer sortCustomizer() {
return s -> s.setPropertyDelimiter("<-->");
}
如果设置现有的属性 MethodArgumentResolver 不足以满足您的目标,请扩大其中一个
SpringDataWebConfiguration 或启用 HATEOAS 的等效项,笼罩 pageableResolver()orsortResolver() 办法,并导入您的自定义配置文件而不是应用 @Enable 正文。
如果您须要从申请中解析多个 Pageable 或 Sort 实例(例如,对于多个表),您能够应用 Spring 的 @Qualifier 正文来辨别一个。而后申请参数必须以 ${qualifier}_. 以下示例显示了生成的办法签名:
String showUsers(Model model,
@Qualifier("thing1") Pageable first,
@Qualifier("thing2") Pageable second) {…}
您必须填充 thing1_page、thing2_page 等。
Pageable 传入办法的默认值相当于 a PageRequest.of(0, 20),但您能够应用参数 @PageableDefault 上的注解来自定义它 Pageable。
Pageables 的超媒体反对
春天 HATEOAS 附带的示意模型类(PagedResources),它容许一个丰盛的内容 Page 实例与必要的 Page 元数据,以及链接,让用户轻松地浏览网页。aPage 到 a 的转换 PagedResources 是由 Spring HATEOASResourceAssembler 接口的实现实现的,称为 PagedResourcesAssembler. 以下示例显示了如何应用 aPagedResourcesAssembler 作为控制器办法参数:
示例 70. 应用 PagedResourcesAssembler 作为控制器办法参数
@Controller
class PersonController {
@Autowired PersonRepository repository;
@RequestMapping(value = “/persons”, method = RequestMethod.GET)
HttpEntity<PagedResources<Person>> persons(Pageable pageable,
PagedResourcesAssembler assembler) {Page<Person> persons = repository.findAll(pageable);
return new ResponseEntity<>(assembler.toResources(persons), HttpStatus.OK);
}
}
启用配置,如后面的示例所示,能够 PagedResourcesAssembler 将 用作控制器办法参数。调用 toResources(…)它有以下成果:
的内容 Page 成为 PagedResources 实例的内容。
该 PagedResources 对象 PageMetadata 附加了一个实例,并填充了来自 Page 和底层的信息 PageRequest。
将 PagedResources 可能会 prev 和 next 连贯链路,依据页面的状态。链接指向办法映射到的 URI。增加到办法中的分页参数与设置相匹配,PageableHandlerMethodArgumentResolver 以确保稍后能够解析链接。
假如咱们 Person 在数据库中有 30 个实例。您当初能够触发申请 () 并查看相似于以下内容的输入:GET
http://localhost:8080/persons
{“links” : [ { “rel” : “next”,
"href" : "http://localhost:8080/persons?page=1&size=20" }
],
“content” : [
… // 20 Person instances rendered here
],
“pageMetadata” : {
"size" : 20,
"totalElements" : 30,
"totalPages" : 2,
"number" : 0
}
}
汇编器生成了正确的 URI,并且还抉择了默认配置以将参数解析 Pageable 为行将到来的申请。这意味着,如果您更改该配置,链接会主动遵循更改。默认状况下,汇编器指向调用它的控制器办法,但您能够通过传递自定义 Link 作为根底来构建分页链接,从而重载
PagedResourcesAssembler.toResource(…) 办法来自定义它。
Spring Data Jackson 模块
外围模块和一些特定于商店的模块附带一组杰克逊模块,用于 Spring Data 域应用的类型,如
org.springframework.data.geo.Distance 和 org.springframework.data.geo.Point。
一旦启用 Web 反对并可用,
com.fasterxml.jackson.databind.ObjectMapper 就会导入这些模块。
在初始化期间 SpringDataJacksonModules,像
SpringDataJacksonConfiguration, 被基础设施拾取,以便申明的 com.fasterxml.jackson.databind.Modules 可供 Jackson 应用 ObjectMapper。
以下域类型的数据绑定混合由公共基础设施注册。
org.springframework.data.geo.Distance
org.springframework.data.geo.Point
org.springframework.data.geo.Box
org.springframework.data.geo.Circle
org.springframework.data.geo.Polygon
单个模块可能会提供额定的 SpringDataJacksonModules.
无关详细信息,请参阅商店特定局部。
Web 数据绑定反对
您能够应用 Spring Data 投影(在[projections] 中形容)通过应用 JSONPath 表达式(须要 Jayway JsonPath 或 XPath 表达式(须要 XmlBeam)来绑定传入的申请负载,如以下示例所示:
示例 71. 应用 JSONPath 或 XPath 表达式的 HTTP 无效负载绑定
@ProjectedPayload
public interface UserPayload {
@XBRead(“//firstname”)
@JsonPath(“$..firstname”)
String getFirstname();
@XBRead(“/lastname”)
@JsonPath({“$.lastname”, “$.user.lastname”})
String getLastname();
}
能够应用在后面的例子中为一个 Spring MVC 处理程序办法参数或通过应用所示类型
ParameterizedTypeReference 上的办法之一 RestTemplate。后面的办法申明将尝试 firstname 在给定文档中查找任何地位。该 lastnameXML 查问是对输出文档的顶层进行。它的 JSON 变体 lastname 首先尝试顶级,但如果前者不返回值,也会尝试 lastname 嵌套在 user 子文档中。这样,源文档构造的更改能够轻松缓解,而无需客户端调用公开的办法(通常是基于类的无效负载绑定的毛病)。
如[projections] 中所述,反对嵌套投影。如果该办法返回简单的非接口类型,ObjectMapper 则应用 Jackson 来映射最终值。
对于 Spring MVC,必要的转换器在流动时会主动注册,@
EnableSpringDataWebSupport 并且所需的依赖项在类门路中可用。对于应用 RestTemplate,注册一个 ProjectingJackson2HttpMessageConverter(JSON)或 XmlBeamHttpMessageConverter 手动。
无关更多信息,请参阅标准 Spring 数据示例存储库中的 Web 投影示例。
Querydsl 网络反对
对于那些具备 QueryDSL 集成的商店,您能够从 Request 查问字符串中蕴含的属性派生查问。
思考以下查问字符串:
?firstname=Dave&lastname=Matthews
给定 User 后面示例中的对象,您能够应用 将查问字符串解析为以下值
QuerydslPredicateArgumentResolver,如下所示:
QUser.user.firstname.eq(“Dave”).and(QUser.user.lastname.eq(“Matthews”))
@
EnableSpringDataWebSupport 当在类门路中找到 Querydsl 时,该性能会主动启用。
向 @QuerydslPredicate 办法签名增加 a 提供了一个即用型 Predicate,您能够应用
QuerydslPredicateExecutor.
类型信息通常从办法的返回类型中解析。因为该信息不肯定与域类型匹配,因而应用 的 root 属性可能是个好主见 QuerydslPredicate。
以下示例显示了如何 @QuerydslPredicate 在办法签名中应用:
@Controller
class UserController {
@Autowired UserRepository repository;
@RequestMapping(value = “/”, method = RequestMethod.GET)
String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate,
Pageable pageable, @RequestParam MultiValueMap<String, String> parameters) {model.addAttribute("users", repository.findAll(predicate, pageable));
return "index";
}
}
将查问字符串参数解析为匹配 Predicatefor User。
默认绑定如下:
Object 在简略的属性上 eq。
Object 像属性一样的汇合 contains。
Collection 在简略的属性上 in。
您能够通过 bindings 属性 @QuerydslPredicate 或应用 Java 8default methods 并将 QuerydslBinderCustomizer 办法增加到存储库接口来自定义这些绑定,如下所示:
interface UserRepository extends CrudRepository<User, String>,
QuerydslPredicateExecutor<User>,
QuerydslBinderCustomizer<QUser> {
@Override
default void customize(QuerydslBindings bindings, QUser user) {
bindings.bind(user.username).first((path, value) -> path.contains(value))
bindings.bind(String.class)
.first((StringPath path, String value) -> path.containsIgnoreCase(value));
bindings.excluding(user.password);
}
}
QuerydslPredicateExecutor 提供对 Predicate.
QuerydslBinderCustomizer 存储库界面上定义的主动拾取和快捷方式 @QuerydslPredicate(bindings=…)。
将 username 属性的绑定定义为简略 contains 绑定。
将 String 属性的默认绑定定义为不辨别大小写的 contains 匹配。
password 从 Predicate 解析中排除该属性。
您能够
QuerydslBinderCustomizerDefaults 在利用来自存储库或 @QuerydslPredicate.