如何用Spring Web Client从HAL格式响应加载类字段并关联地址数据
用Spring WebClient处理HAL格式响应并关联嵌套资源
1. 定义实体类
适配HAL格式的响应结构,借助Spring HATEOAS的RepresentationModel自动处理_links字段,同时定义业务实体:
Person实体类
import org.springframework.hateoas.RepresentationModel; import java.util.List; public class Person extends RepresentationModel<Person> { private Long id; private String name; private List<Address> addresses; // 构造器、getter、setter public Person() {} public Person(Long id, String name) { this.id = id; this.name = name; } // 自行补充getter和setter方法 }
Address实体类
public class Address { private String house; private String street; private String city; private String country; private String pincode; // 构造器、getter、setter public Address() {} // 自行补充getter和setter方法 }
HAL地址响应包装类
针对地址接口返回的_embedded结构,定义包装类解析数据:
import java.util.List; public class AddressEmbeddedResponse { private List<Address> addresses; public List<Address> getAddresses() { return addresses; } public void setAddresses(List<Address> addresses) { this.addresses = addresses; } }
注意:原地址响应中的
_embaded是拼写错误,符合HAL规范的字段应为_embedded;若接口确实返回错误拼写,需给包装类字段添加@JsonProperty("_embaded")注解适配。
2. 配置WebClient实例
创建全局WebClient实例供业务调用:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.WebClient; @Configuration public class WebClientConfig { @Bean public WebClient webClient() { return WebClient.builder() .baseUrl("http://localhost:8080") .build(); } }
3. 编写业务调用逻辑
通过WebClient链式调用两个接口,解析HAL响应并关联数据:
import org.springframework.hateoas.Link; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @Service public class PersonService { private final WebClient webClient; public PersonService(WebClient webClient) { this.webClient = webClient; } public Mono<Person> getPersonWithAddresses(Long personId) { // 1. 调用人员接口获取HAL格式的Person数据 return webClient.get() .uri("/person/{id}", personId) .retrieve() .bodyToMono(Person.class) // 2. 从Person的_links中提取addresses链接,调用地址接口 .flatMap(person -> { Link addressesLink = person.getLink("addresses") .orElseThrow(() -> new RuntimeException("HAL响应中未找到addresses链接")); return webClient.get() .uri(addressesLink.getHref()) .retrieve() .bodyToMono(AddressEmbeddedResponse.class) // 3. 将地址列表设置到Person对象中 .map(embeddedResponse -> { person.setAddresses(embeddedResponse.getAddresses()); return person; }); }); } }
4. 使用示例
在控制器中调用业务方法:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController public class PersonController { private final PersonService personService; public PersonController(PersonService personService) { this.personService = personService; } @GetMapping("/person-with-addresses/{id}") public Mono<Person> getPersonWithAddresses(@PathVariable Long id) { return personService.getPersonWithAddresses(id); } }
内容的提问来源于stack exchange,提问作者Rajesh Kumar
相关产品推荐
相关产品推荐

