实现远程调用案例
在order-service服务中,有一个根据id查询订单的接口:
根据id查询订单,返回值是Order对象,如图:
其中的user为null
在user-service中有一个根据id查询用户的接口:
查询的结果如图:
案例需求
修改order-service中的根据id查询订单业务,要求在查询订单的同时,根据订单中包含的userId查询出用户信息,一起返回。
从订单模块向用户模块发起远程调用,然后把查到结果做一个组合。
因此,我们需要在order-service中 向user-service发起一个http的请求,调用http://localhost:8081/user/{userId}这个接口。
所以问题就变成了:如何在Java代码中发送HTTP请求。
大概的步骤是这样的:
-
注册一个RestTemplate的实例到Spring容器
-
修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User
-
将查询的User填充到Order对象,一起返回
注册RestTemplate
Spring提供了一个工具:RestTemplate,这个工具就是Spring提供给我们来发各种各样的HTTP请求的。
http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可。
如下,是通过一种Bean的方式把RestTemplate注册为Spring的一个对象,将来可以在任何地方注入这个对象来用了
由于Bean的注入只能放到配置类里,而SpringBoot的启动类本身也是配置类,所以完全可以在启动类里去写Bean的注入。
首先,我们在order-service服务中的OrderApplication启动类中,注册RestTemplate实例:
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* 创建RestTemplate并注入Spring容器
* @return
*/
@Bean
public RestTemplate restTemplate () {
return new RestTemplate();
}
}
实现远程调用
修改order-service服务中的cn.itcast.order.service包下的OrderService类中的queryOrderById方法:
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.利用RestTemplate发起http请求,查询用户
// 参数1:URL路径,这个和浏览器里的路径是完全一样的
// 2.1 url路径
String url = "http://localhost:8081/user/" + order.getUserId();
// 2.2 发送http请求:实现远程调用
// 得到的结果是一个JSON风格,但我们想要的是user对象,但是RestTemplate非常的智能
// getForObject:发送get方式的请求
// 参数2:responseType 返回值类型。例如这里填User.class,它会自动帮你反序列化成User类型
User user = restTemplate.getForObject(url, User.class);
// 封装user到Order
order.setUser(user);
// 4.返回
return order;
}