6. 客户端支持

本节介绍了春季HATEOAS对客户的支持。spring-doc.cadn.net.cn

6.1. 特拉弗森

Spring HATEOAS 提供客户端服务遍历的 API。它的灵感来源于 Traverson JavaScript 库。 以下示例展示了如何使用它:spring-doc.cadn.net.cn

Map<String, Object> parameters = new HashMap<>();
parameters.put("user", 27);

Traverson traverson = new Traverson(URI.create("http://localhost:8080/api/"), MediaTypes.HAL_JSON);
String name = traverson
    .follow("movies", "movie", "actor").withTemplateParameters(parameters)
    .toObject("$.name");

你可以设置一个特拉弗森通过指向 REST 服务器并配置你想设置的媒体类型来实现实例接受头。然后你可以定义你想要发现和遵循的关系名称。关系名称可以是简单名称,也可以是 JSONPath 表达式(以 开头)。$spring-doc.cadn.net.cn

样本随后将参数映射输入特拉弗森实例。这些参数用于扩展遍历过程中发现的URI(模板化)。遍历通过访问最终遍历的表示来结束。在前面的例子中,我们评估一个 JSONPath 表达式来访问演员的名称。spring-doc.cadn.net.cn

上述例子是遍历的最简单版本,其中相对值是字符串,每跳都应用相同的模板参数。spring-doc.cadn.net.cn

每个层级都有更多自定义模板参数的选项。 以下示例展示了这些选项。spring-doc.cadn.net.cn

ParameterizedTypeReference<EntityModel<Item>> resourceParameterizedTypeReference = new ParameterizedTypeReference<EntityModel<Item>>() {};

EntityModel<Item> itemResource = traverson.//
    follow(rel("items").withParameter("projection", "noImages")).//
    follow("$._embedded.items[0]._links.self.href").//
    toObject(resourceParameterizedTypeReference);

静电声rel(...)函数是一种方便定义单一.用.withParameter(key, value)这使得指定 URI 模板变量变得简单。spring-doc.cadn.net.cn

.withParameter()退还一个新的可链式的对象。你可以串联起尽可能多的.withParameter随你便。结果是一本定义。 以下示例展示了一种实现这一目标的方法:
ParameterizedTypeReference<EntityModel<Item>> resourceParameterizedTypeReference = new ParameterizedTypeReference<EntityModel<Item>>() {};

Map<String, Object> params = Collections.singletonMap("projection", "noImages");

EntityModel<Item> itemResource = traverson.//
    follow(rel("items").withParameters(params)).//
    follow("$._embedded.items[0]._links.self.href").//
    toObject(resourceParameterizedTypeReference);

你也可以装满整个地图通过使用.withParameters(Map).spring-doc.cadn.net.cn

跟随()是可链式的,意味着你可以串联多个跳数,如前面示例所示。你可以选择多字符串相对值(跟(“项目”,“项目”))或具有特定参数的单跳。

6.1.1.EntityModel<T>与。CollectionModel<T>

目前展示的示例展示了如何绕过 Java 的类型擦除,将单个 JSON 格式资源转换为EntityModel<Item>对象。但是,如果你拿到一个像\_嵌入式HAL收藏? 只需稍作调整即可实现,如下示例所示:spring-doc.cadn.net.cn

CollectionModelType<Item> collectionModelType =
    new TypeReferences.CollectionModelType<Item>() {};

CollectionModel<Item> itemResource = traverson.//
    follow(rel("items")).//
    toObject(collectionModelType);

它不是取用单个资源,而是将集合反序列化为CollectionModel.spring-doc.cadn.net.cn

在处理支持超媒体的表示时,一个常见任务是寻找具有特定关系类型的链接。Spring HATEOAS 提供了基于 JSONPath 的实现链接发现器无论是默认表示渲染还是开箱即用的HAL接口。使用@EnableHypermediaSupport我们会自动将支持配置超媒体类型的实例暴露为 Spring Bean。spring-doc.cadn.net.cn

或者,你也可以按照以下方式设置和使用实例:spring-doc.cadn.net.cn

String content = "{'_links' :  { 'foo' : { 'href' : '/foo/bar' }}}";
LinkDiscoverer discoverer = new HalLinkDiscoverer();
Link link = discoverer.findLinkWithRel("foo", content);

assertThat(link.getRel(), is("foo"));
assertThat(link.getHref(), is("/foo/bar"));

6.3. 配置Web客户端实例

如果你需要配置Web客户端说超媒体,很简单。联系HypermediaWebClientConfigurer如下所示:spring-doc.cadn.net.cn

例子43。配置Web客户端你自己
@Bean
WebClient.Builder hypermediaWebClient(HypermediaWebClientConfigurer configurer) { (1)
 return configurer.registerHypermediaTypes(WebClient.builder()); (2)
}
1 在你的内部@Configuration同学,拿一份HypermediaWebClientConfigurer豆泉 HATEOAS 登记。
2 在创建WebClient.Builder,使用配置器注册超媒体类型。
什么HypermediaWebClientConfigurer它是否注册了所有正确的编码器和解码器WebClient.Builder.要善加利用它, 你需要在应用中注入构建器,并运行build()生成Web客户端.

如果你用的是Spring Boot,还有另一种方法:那WebClientCustomizer.spring-doc.cadn.net.cn

例子44。让 Spring Boot 来配置
@Bean (4)
WebClientCustomizer hypermediaWebClientCustomizer(HypermediaWebClientConfigurer configurer) { (1)
    return webClientBuilder -> { (2)
        configurer.registerHypermediaTypes(webClientBuilder); (3)
    };
}
1 创建春季豆时,请请求一份春季HATEOAS的副本HypermediaWebClientConfigurer豆。
2 使用 Java 8 lambda 表达式来定义WebClientCustomizer.
3 在函数调用中,应用registerHypermediaTypes方法。
4 把整个文件作为 Spring Bean 返回,这样 Spring Boot 就能接收并应用到它的自动配置中WebClient.Builder豆。

在这个阶段,每当你需要混凝土时Web客户端,简单地注入WebClient.Builder并用build().这Web客户端实例 能够通过超媒体进行互动。spring-doc.cadn.net.cn

6.4. 配置WebTestClient实例

在处理超媒体支持的表示时,一个常见任务是通过以下方式运行各种测试WebTestClient.spring-doc.cadn.net.cn

要配置 的实例WebTestClient在一个测试案例中,看看这个例子:spring-doc.cadn.net.cn

例子45。配置WebTestClient使用春季HATEOAS时
@Test // #1225
void webTestClientShouldSupportHypermediaDeserialization() {

  // Configure an application context programmatically.
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  context.register(HalConfig.class); (1)
  context.refresh();

  // Create an instance of a controller for testing
  WebFluxEmployeeController controller = context.getBean(WebFluxEmployeeController.class);
  controller.reset();

  // Extract the WebTestClientConfigurer from the app context.
  HypermediaWebTestClientConfigurer configurer = context.getBean(HypermediaWebTestClientConfigurer.class);

  // Create a WebTestClient by binding to the controller and applying the hypermedia configurer.
  WebTestClient client = WebTestClient.bindToApplicationContext(context).build().mutateWith(configurer); (2)

  // Exercise the controller.
  client.get().uri("http://localhost/employees").accept(HAL_JSON) //
      .exchange() //
      .expectStatus().isOk() //
      .expectBody(new TypeReferences.CollectionModelType<EntityModel<Employee>>() {}) (3)
      .consumeWith(result -> {
        CollectionModel<EntityModel<Employee>> model = result.getResponseBody(); (4)

        // Assert against the hypermedia model.
        assertThat(model.getRequiredLink(IanaLinkRelations.SELF)).isEqualTo(Link.of("http://localhost/employees"));
        assertThat(model.getContent()).hasSize(2);
      });
}
1 注册你的配置类,使用@EnableHypermediaSupport以启用HAL支持。
2 HypermediaWebTestClientConfigurer应用超媒体支持。
3 请求回复CollectionModel<EntityModel<Employee>>使用春季HATEOAS的类型参考。集合模型类型助手。
4 在获得春季HATEOAS格式的“主体”后,提出反对意见!
WebTestClient是不可变的值类型,所以你无法原地更改它。HypermediaWebClientConfigurer返回变异的 变体必须捕获才能使用。

如果你用的是Spring Boot,还有其他选项,比如这样:spring-doc.cadn.net.cn

例子46。配置WebTestClient使用Spring Boot时
@SpringBootTest
@AutoConfigureWebTestClient (1)
class WebClientBasedTests {

    @Test
    void exampleTest(@Autowired WebTestClient.Builder builder, @Autowired HypermediaWebTestClientConfigurer configurer) { (2)
        client = builder.apply(configurer).build(); (3)

        client.get().uri("/") //
                .exchange() //
                .expectBody(new TypeReferences.EntityModelType<Employee>() {}) (4)
                .consumeWith(result -> {
                    // assert against this EntityModel<Employee>!
                });
    }
}
1 这是 Spring Boot 的测试注释,可以配置WebTestClient.Builder为了这门考试课。
2 Autowire Spring靴WebTestClient.Builder架构工人以及Spring HATEOAS的配置器作为方法参数。
3 HypermediaWebTestClientConfigurer注册支持超媒体。
4 信号你想要一个EntityModel<Employee>返回的使用类型参考.

同样,你也可以使用与前面例子类似的断言。spring-doc.cadn.net.cn

还有许多其他方法可以设计测试案例。WebTestClient可以绑定到控制器、函数和URL。本节并非用来展示这些内容。相反,这里给你一些入门的例子。重要的是,通过申请HypermediaWebTestClientConfigurer,任意WebTestClient可以修改以处理超媒体。spring-doc.cadn.net.cn

6.5. 配置 RestTemplate 实例

如果你想创建自己的副本Rest模板配置为超媒体语音,你可以使用HypermediaRestTemplateConfigurer:spring-doc.cadn.net.cn

例子47。配置Rest模板你自己
/**
 * Use the {@link HypermediaRestTemplateConfigurer} to configure a {@link RestTemplate}.
 */
@Bean
RestTemplate hypermediaRestTemplate(HypermediaRestTemplateConfigurer configurer) { (1)
	return configurer.registerHypermediaTypes(new RestTemplate()); (2)
}
1 在你的内部@Configuration同学,拿一份HypermediaRestTemplateConfigurer豆泉 HATEOAS 登记。
2 在创建Rest模板使用配置器应用超媒体类型。

你可以自由地将此模式应用于任意Rest模板无论是创建注册豆子,还是在你定义的服务中,都需要这些。spring-doc.cadn.net.cn

如果你用的是Spring Boot,还有另一种方法。spring-doc.cadn.net.cn

总体来说,Spring Boot已经不再使用注册Rest模板在应用语境中。spring-doc.cadn.net.cn

为弥补这一点,Spring靴提供了Rest模板构建器.这个自动配置的豆子可以让你定义用于制作的各种豆子 一个Rest模板实例。你要求一个Rest模板构建器豆子,叫它build()然后应用最终设置(如凭证及其他细节)。spring-doc.cadn.net.cn

要注册基于超媒体的消息转换器,请在代码中添加以下内容:spring-doc.cadn.net.cn

例子48。让 Spring Boot 来配置
@Bean (4)
RestTemplateCustomizer hypermediaRestTemplateCustomizer(HypermediaRestTemplateConfigurer configurer) { (1)
    return restTemplate -> { (2)
        configurer.registerHypermediaTypes(restTemplate); (3)
    };
}
1 创建春季豆时,请请求一份春季HATEOAS的副本HypermediaRestTemplateConfigurer豆。
2 使用 Java 8 lambda 表达式来定义RestTemplateCustomizer.
3 在函数调用中,应用registerHypermediaTypes方法。
4 把整个文件作为 Spring Bean 返回,这样 Spring Boot 就能接收并应用到它的自动配置中Rest模板构建器.

在这个阶段,每当你需要混凝土时Rest模板,简单地注入Rest模板构建器并用build().这Rest模板实例 能够通过超媒体进行互动。spring-doc.cadn.net.cn