说明

SpringWeb 提供了一个 RestTemplate 模板工具类,对基于 Http 的客户端进行了封装,并且实现了对象与 json 的序列化和反序列化,非常方便。RestTemplate 并没有限定 Http 的客户端类型,而是进行了抽象,目前常用的3种都有支持

  1. HttpClient
  2. OkHttp
  3. JDK原生的URLConnection(默认的)

    demo

    既然 RestTemplate 的目的是实现远程调用,那么就需要有一个服务的提供者,和一个服务的调用者,两者必须是独立运行的服务。
    但是为了方便项目的学习,我们会创建一个聚合项目,然后把服务的提供者、调用者作为其中的两个模块。

    创建父工程

    创建一个父工程,用来管理依赖,聚合子工程
    此父工程是用来管理子工程的,所以可以删除 src 目录,目录结构如下
    SpringCloud_RestTemplate - 图1
    pom 文件中引入相关依赖,打包方式设置为 pom
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0</modelVersion>
    6. <groupId>com.it.learn</groupId>
    7. <artifactId>restTemplate-demo</artifactId>
    8. <version>1.0-SNAPSHOT</version>
    9. <packaging>pom</packaging>
    10. <parent>
    11. <groupId>org.springframework.boot</groupId>
    12. <artifactId>spring-boot-starter-parent</artifactId>
    13. <version>2.1.12.RELEASE</version>
    14. <relativePath/>
    15. </parent>
    16. <properties>
    17. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    18. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    19. <java.version>1.8</java.version>
    20. <spring-cloud.version>Greenwich.SR5</spring-cloud.version>
    21. <mysql.version>5.1.47</mysql.version>
    22. </properties>
    23. <dependencyManagement>
    24. <dependencies>
    25. <!-- springCloud -->
    26. <dependency>
    27. <groupId>org.springframework.cloud</groupId>
    28. <artifactId>spring-cloud-dependencies</artifactId>
    29. <version>${spring-cloud.version}</version>
    30. <type>pom</type>
    31. <scope>import</scope>
    32. </dependency>
    33. <!-- mysql驱动 -->
    34. <dependency>
    35. <groupId>mysql</groupId>
    36. <artifactId>mysql-connector-java</artifactId>
    37. <version>${mysql.version}</version>
    38. </dependency>
    39. <!--mybatis-->
    40. <dependency>
    41. <groupId>org.mybatis.spring.boot</groupId>
    42. <artifactId>mybatis-spring-boot-starter</artifactId>
    43. <version>2.1.1</version>
    44. </dependency>
    45. </dependencies>
    46. </dependencyManagement>
    47. <dependencies>
    48. <dependency>
    49. <groupId>org.projectlombok</groupId>
    50. <artifactId>lombok</artifactId>
    51. </dependency>
    52. </dependencies>
    53. </project>

    服务提供者

    我们新建一个项目,对外提供查询用户的服务。
    此工程为上述父工程的子工程
    结构如下
    SpringCloud_RestTemplate - 图2
    导入相关依赖
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <parent>
    6. <artifactId>restTemplate-demo</artifactId>
    7. <groupId>com.it.learn</groupId>
    8. <version>1.0-SNAPSHOT</version>
    9. </parent>
    10. <modelVersion>4.0.0</modelVersion>
    11. <artifactId>user-service</artifactId>
    12. <properties>
    13. <maven.compiler.source>8</maven.compiler.source>
    14. <maven.compiler.target>8</maven.compiler.target>
    15. </properties>
    16. <dependencies>
    17. <dependency>
    18. <groupId>org.springframework.boot</groupId>
    19. <artifactId>spring-boot-starter-web</artifactId>
    20. </dependency>
    21. <dependency>
    22. <groupId>mysql</groupId>
    23. <artifactId>mysql-connector-java</artifactId>
    24. </dependency>
    25. <!--mybatis-->
    26. <dependency>
    27. <groupId>org.mybatis.spring.boot</groupId>
    28. <artifactId>mybatis-spring-boot-starter</artifactId>
    29. </dependency>
    30. </dependencies>
    31. <build>
    32. <plugins>
    33. <plugin>
    34. <groupId>org.springframework.boot</groupId>
    35. <artifactId>spring-boot-maven-plugin</artifactId>
    36. </plugin>
    37. </plugins>
    38. </build>
    39. </project>
    新建 application.yml 配置文件,编写相关配置信息
    1. server:
    2. port: 8081
    3. spring:
    4. datasource:
    5. driver-class-name: com.mysql.jdbc.Driver
    6. url: jdbc:mysql://192.168.206.99:3306/db2?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
    7. username: root
    8. password: root
    9. application:
    10. name: user-service # 服务的名称不能使用下划线
    11. mybatis:
    12. type-aliases-package: com.it.learn.pojo
    13. configuration:
    14. map-underscore-to-camel-case: true
    15. logging:
    16. level:
    17. com.it.learn: debug
    编写 UserServiceApplication 启动类
    1. package com.it.learn;
    2. import org.mybatis.spring.annotation.MapperScan;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. @SpringBootApplication
    6. @MapperScan("com.it.learn.mapper")
    7. public class UserServiceApplication {
    8. public static void main(String[] args) {
    9. SpringApplication.run(UserServiceApplication.class);
    10. }
    11. }
    编写 pojo 实体类
    1. package com.it.learn.pojo;
    2. import lombok.Data;
    3. @Data
    4. public class User {
    5. private Long id;
    6. private String userName;
    7. private String password;
    8. private String name;
    9. private int age;
    10. private String email;
    11. }
    在表中有对应数据表
    SpringCloud_RestTemplate - 图3
    新建 UserMapper
    1. package com.it.learn.mapper;
    2. import com.it.learn.pojo.User;
    3. import org.apache.ibatis.annotations.Param;
    4. import org.apache.ibatis.annotations.Select;
    5. public interface UserMapper {
    6. @Select("select * from tb_user where id = #{id}")
    7. public User findUserById(@Param("id") Long id);
    8. }
    新建 UserService
    1. package com.it.learn.service;
    2. import com.it.learn.pojo.User;
    3. public interface UserService {
    4. public User findUserById(Long id);
    5. }
    新建 UserServiceImpl
    1. package com.it.learn.service.impl;
    2. import com.it.learn.mapper.UserMapper;
    3. import com.it.learn.pojo.User;
    4. import com.it.learn.service.UserService;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. @Service("userService")
    8. public class UserServiceImpl implements UserService {
    9. @Autowired
    10. private UserMapper userMapper;
    11. @Override
    12. public User findUserById(Long id) {
    13. return userMapper.findUserById(id);
    14. }
    15. }
    新建 UserController
    1. package com.it.learn.web;
    2. import com.it.learn.pojo.User;
    3. import com.it.learn.service.UserService;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.web.bind.annotation.PathVariable;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.bind.annotation.RestController;
    8. @RestController
    9. @RequestMapping("user")
    10. public class UserController {
    11. @Autowired
    12. private UserService userService;
    13. @RequestMapping("/{id}")
    14. public User findUserById(@PathVariable("id") Long id){
    15. return this.userService.findUserById(id);
    16. }
    17. }
    服务提供者项目结构图
    SpringCloud_RestTemplate - 图4
    启动项目,测试下, http://localhost:8081/user/5
    SpringCloud_RestTemplate - 图5

    服务调用者

    与上面类似,这里不再赘述,需要注意的是,我们调用 user-service 的功能,因此不需要 mybatis 相关依赖了。
    新建完,结构如下
    SpringCloud_RestTemplate - 图6
    pom 文件引入了 webstarter 依赖,而 webstarter 中会包含 RestTemplate 相关依赖。
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <parent>
    6. <artifactId>restTemplate-demo</artifactId>
    7. <groupId>com.it.learn</groupId>
    8. <version>1.0-SNAPSHOT</version>
    9. </parent>
    10. <modelVersion>4.0.0</modelVersion>
    11. <artifactId>consumer-service</artifactId>
    12. <properties>
    13. <maven.compiler.source>8</maven.compiler.source>
    14. <maven.compiler.target>8</maven.compiler.target>
    15. </properties>
    16. <!-- 导入web启动器 -->
    17. <dependencies>
    18. <dependency>
    19. <groupId>org.springframework.boot</groupId>
    20. <artifactId>spring-boot-starter-web</artifactId>
    21. </dependency>
    22. </dependencies>
    23. </project>
    新建启动类,并且注册一个 RestTemplate 实例
    1. package com.it.learn;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.web.client.RestTemplate;
    6. @SpringBootApplication
    7. public class UserConsumerApplication {
    8. public static void main(String[] args) {
    9. SpringApplication.run(UserConsumerApplication .class);
    10. }
    11. // 注册RestTemplate的对象到Spring的容器中
    12. @Bean
    13. public RestTemplate restTemplate(){
    14. return new RestTemplate();
    15. }
    16. }
    新建 pojo 实体类
    1. package com.it.learn.pojo;
    2. import lombok.Data;
    3. @Data
    4. public class User {
    5. private Long id;
    6. private String userName;
    7. private String password;
    8. private String name;
    9. private int age;
    10. private String email;
    11. }
    新建 UserController,在 controller 中直接调用 RestTemplate,远程访问 user-service 的服务接口
    RestTemplate会向 http://localhost:8081 地址发起请求,并且得到响应的 JSON 数据。然后会将 JSON 数据反序列化为 User 类型。
    1. package com.it.learn.controller;
    2. import com.it.learn.pojo.User;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.web.bind.annotation.PathVariable;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.RestController;
    7. import org.springframework.web.client.RestTemplate;
    8. @RestController
    9. @RequestMapping("consumer")
    10. public class UserController {
    11. // 发送基于http协议的远程过程调用(2个服务器相互调用)
    12. @Autowired
    13. private RestTemplate restTemplate;
    14. @RequestMapping("/{id}")
    15. public User findUserById(@PathVariable("id") Long id){
    16. String url = "http://127.0.0.1:8081/user/" + id;
    17. User user = restTemplate.getForObject(url, User.class);
    18. return user;
    19. }
    20. }
    项目结构图
    SpringCloud_RestTemplate - 图7
    启动项目,进行测试,http://localhost:8080/consumer/6
    SpringCloud_RestTemplate - 图8

    调用链路

    SpringCloud_RestTemplate - 图9
    项目demo:
    restTemplate-demo