【微服务远程调用】基于RestTemplate发送HTTP请求实现微服务远程调用

请添加图片描述




1. 情景

  • 我编写的订单微服务查询订单时,无法跨越数据库查询订单所关联的用户 user 。因此下图中订单数据的 user 字段为 null

    image-20220927160707910

  • 本节,我们将演示订单微服务 order-service 如何通过远程调用用户微服务 user-service 的根据用户 ID 查询用户的接口,来查询订单的同时,把订单所属的用户信息一起返回,如下图所示。

    image-20221215092416661


2. 远程调用方式分析

  • 订单微服务 order-service 也可以像浏览器一样,向用户微服务 user-service 发起 HTTP 请求,那么用户微服务就响应对应的用户信息给订单微服务。订单微服务获取到用户数据后,再结合本地的订单数据库查询出的订单数据,就组合出了订单及其所属的用户信息。因此,现在的问题的核心就变成了:如何在 Java 代码中发起 HTTP 请求?

    image-20221215092819744


3. 远程调用步骤


3.1 注册 RestTemplate

  • RestTemplate 是 Spring 提供的发起 HTTP 请求的工具类。

    image-20221215093524151

  • 首先,我们要在订单微服务 order-serviceOrderApplication.java 应用启动类中注册 RestTemplate 。这样,将来我们就可以在任何地方注入 RestTemplate 对象来使用。

    @MapperScan("cn.itcast.order.mapper")
    @SpringBootApplication
    @Slf4j
    public class OrderApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(OrderApplication.class, args);
            log.info("订单微服务启动成功");
        }
    
        // 注册RestTemplate,用来发起HTTP请求远程调用
        @Bean
        public RestTemplate restTemplate() {
          
          
            return new RestTemplate();
        }
    }
    

    【小贴士】

    @Bean 的注入只能放在 Spring 的配置类中。而启动类 OrderApplication.java 带有注解 @SpringBootApplication 本身也是配置类。因此,可以在启动类中写 @Bean 的注入。


3.2 修改订单业务层

  • 订单的实体类 Order.java 中,有用户 ID 的字段 userId 。因此我们可以根据字段 userId 向用户微服务发起 HTTP 请求。首先把 RestTemplate 自动注入进来。 在这里插入图片描述

  • 然后,如果你要发 GET 请求,就使用 getForObjct() 方法。其中,第一个入参 URI url 就跟浏览器向用户微服务发起的 HTTP 请求地址是一样的,如 http://localhost:8081/user/1 ;第二个入参 responseType 指的是返回值类型,RestTemplate 非常智能,正常情况下,HTTP 请求后得到的返回值一般都是 JSON 风格的字符串,但这第二个入参 responseType 指定后,RestTemplate 就会自动地帮我们把 JSON 数据反序列化成你指定的 Java 实体类对象。

    image-20221215095358455

  • OrderService.java

    @Service
    public class OrderService {
          
          
    
        @Autowired
        private OrderMapper orderMapper;
        // 自动注入RestTemplate,用于发起HTTP请求远程调用
        @Autowired
        private RestTemplate restTemplate;
    
        public Order queryOrderById(Long orderId) {
          
          
            // 1.查询订单
            Order order = orderMapper.findById(orderId);
            // 2.使用RestTemplate发起HTTP请求,查询订单所属用户信息
            // 2.1 根据查询的订单order中的userId动态生成HTTP请求的url
            String url = "http://localhost:8081/user/" + order.getUserId();
            // 2.2 发送HTTP请求,实现远程调用
            User user = restTemplate.getForObject(url, User.class);
            // 3.把远程调用获得的user封装进order对象中
            order.setUser(user);
            // 4.返回order订单信息
            return order;
        }
    }
    

3.3 测试

  • 重启两个微服务,用 Postman 向订单微服务发送根据订单 ID 查询的请求。

    image-20221215100846598

    这样,我们就成功使用 RestTemplate 实现了跨服务的远程调用。


4. 总结

  • 基于 Spring 提供的 RestTemplate 可以发起 HTTP 请求实现微服务之间的远程调用。
  • HTTP 请求做远程调用是与语言无关的调用,只要知道对方的 IP 、端口、接口路径和请求参数即可。

猜你喜欢

转载自blog.csdn.net/Sihang_Xie/article/details/128326024