源码

GitHub:https://github.com/291685399/springcloud-learning/tree/master/springcloud-eureka01

RestTemplate是什么?

RestTemplate是Spring对Http客户端进行封装的一个模板工具类,对常用的Http客户端例如:HttpClient、OKHttp、JDK原生的URLConnection(默认的)都支持。

RestTemplate能做什么?

基于Restful风格可以对远程服务基于http协议进行远程调用

RestTemplate的使用

  • 新建一个父工程,命名为springcloud-eureka01

目录结构如下图:
在这里插入图片描述
pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>
   <!-- springboot -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter</artifactId>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-devtools</artifactId>
       <scope>runtime</scope>
       <optional>true</optional>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
  • 新建模块,命名为eureka-provider01

目录结构如下图:
在这里插入图片描述

pom.xml:

<parent>
    <groupId>com.wyj</groupId>
    <artifactId>springcloud-eureka01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<!-- springdatajpa -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- springboot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mysql -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

ProviderController:

@Controller
public class ProviderController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/findById/{id}")
    @ResponseBody
    public User findById(@PathVariable int id) {
        User user = userService.findById(id);
        return user;
    }
}

UserService:

public interface UserService {
    public User findById(int id);
}

UserServiceImpl:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User findById(int id) {
        Optional<User> userOptional = userRepository.findById(id);
        User user = userOptional.get();
        return user;
    }
}

UserRepository:

public interface UserRepository extends JpaRepository<User, Integer> {
}

User:

@Entity
@Data
public class User implements Serializable {

    @Id
    @GeneratedValue
    private int id;
    private String name;
    private String sex;
    private int age;
    private String address;
    private String phone;
}

application.properties:

server.port=8081
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springcloud-eureka01?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
  • 新建模块,命名为eureka-consumer01

目录结构如下图:
在这里插入图片描述

pom.xml:

<parent>
    <groupId>com.wyj</groupId>
    <artifactId>springcloud-eureka01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<!-- springboot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

ConsumerController:

@Controller
public class ConsumerController{

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/findById/{id}")
    @ResponseBody
    public User findById(@PathVariable int id) {
        User user = restTemplate.getForObject("http://127.0.0.1:8081/findById/" + id, User.class);
        return user;
    }
}

RestConfig:

@Configuration
public class RestConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

User:

@Data
public class User implements Serializable {

    private int id;
    private String name;
    private String sex;
    private int age;
    private String address;
    private String phone;
}

测试使用

分别启动eureka-provider01和eureka-consumer01,启动顺序没关系

浏览器访问http://127.0.0.1:8080/findById/1
在这里插入图片描述

总结

在ConsumerController中,RestTemplate调用远程服务

User user = restTemplate.getForObject("http://127.0.0.1:8081/findById", User.class);

RestTemplate通过getForObject方法传递url地址及实体类的字节码,自动发起请求,接收响应,并且帮我们对响应结果通过SpringMVC内置的Jackson中的ObjectMapper进行json反序列化,最后返回一个User对象

虽然RestTemplate能够调用远程服务,但是这样还存在着很多问题:
1、请求地址http://127.0.0.1:8081/findById硬编码了,如果更换环境,那么需要更改大量的代码
2、并没有一个中心来控制并管理provider和consumer之间的关系与调用
3、使用RestTemplate调用远程服务代码开发量相对而言大,现在的Demo是业务简单,只需要简单调用getForObject就能获取数据。事实上,RestTemplate还有大量基于Http协议的方法,比如delete()、getForEntity()、getForObject()、put()、headForHeaders()等。但是在后期的SpringCloud学习过程中,Feign作为SpringCloud的核心组件,用于远程服务调用,也是基于Http协议,并且支持注解开发,能够大量减少开发量

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐