原题目: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.