1 案例–根据订单id查询订单功能
需求:根据订单id查询订单的同时,把订单所属的用户信息一起返回。
由上一节的测试结果可以看出,订单模块只能查到订单信息,用户模块只能查到用户信息。而用户的需求是,进行订单查询的同时将user信息也一起查到。
因此我们要去修改订单模块的代码,当用户请求进入订单模块时,除了像之前一样查出订单信息之外,还应该根据查出来的userId去查出用户信息。
这个时候不能直接去查询用户模块的数据库,因为上一节讲到,不要开发重复模块以及其他模块的数据库是独立的。
我们只能从订单模块对用户模块发起远程调用,把查到的信息做一个组合。
2 远程调用方式分析
现在我们的User服务对外暴露了一个接口:
请求方式是Get,请求路径是/user/{id}
浏览器发请求,获得用户信息;
如果订单模块也能发出http请求,接收到用户信息,这个时候订单模块再结合本地数据库查询出来的订单信息,就可以组合出了最终的目标。
所以我们的问题就变成了–如何在Java代码中发起http请求。
2.1 注册RestTemplate
在order-service 的OrderApplication中注册RestTemplate。
如图添加如下代码:
/**
* 创建RestTemplate对象并注入Spring容器
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
通过Bean的方式,把RestTemplate注册为Spring的一个对象。将来就可以在别的地方注入这个对象来用。
2.2 发http请求
接下来就可以利用它来发http请求。下面对订单的查询业务做修改找到OrderController:
可以看到在OrderController里面调用了orderService
接下来进入到orderService中(ctrl+左键):
可以看到订单查询完了以后,order里面是没有用户信息的,但是有用户id:
所以我们可以基于userId,去发起http请求查询用户信息。
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.利用RestTemplate发起http请求,查询用户
// 2.1 url路径
String url = "http://localhost:8081/user/"+order.getUserId();
// 2.2 发起http请求,实现远程调用
User user = restTemplate.getForObject(url, User.class);
//封装User到Order
order.setUser(user);
// 4.返回
return order;
}
}
添加的内容:
- 先把RestTemplate注入进来;
- 然后调用restTemplate函数完成发送:
发get请求:restTemplate.getForObject();
发post请求:restTemplate.postForObject();
这里发送get请求; - 第一个参数是url路径;注意:用户id别写死。 从Order对象里取出UserId。
- 得到的结果是json,但这里想要User对象。
这里restTemplate非常智能,它会问你要一个返回值类型:
这里告诉它要一个User对象,它会自动把json反序列化成User对象。
- 封装User对象到Oeder对象中;
接下来重启服务,打开浏览器:
可以看到成功查询到了用户信息。
到这里就实现了跨服务的远程调用。
3 总结
要想实现跨服务的远程调用,其实就是发送http请求。
- 第一:向Spring容器里注入一个RestTemplate对象。
- 第二:利用RestTemplate里面的一个方法getForObject (url路径,返回类型),它就能够帮你把返回的json转换成对应的类型。
微服务调用方式:
- 基于RestTemplate发起的http请求实现远程调用;
- http请求做远程调用是与语言无关的调用,只要知道对方的ip,端口,接口路径,请求参数即可。
By --Suki 2022/12/31
知识内容来自于黑马程序员视频教学和百度百科。博主仅作笔记整理便于回顾学习。如有侵权请私信我。