我们已经了解了SpringCloud服务调用采用的是基于HTTP的REST方式,那么我们就来搭建一个Rest基本的环境
Rest和RPC的区别?
rest和rpc的区别_一只二师兄的博客-CSDN博客_rest和rpc
什么是RestTemplate?
RestTemplate 是一个HTTP客户端,在Spring Cloud的服务调用方使用它我们可以方便的调用HTTP接口,支持GET、POST、PUT、DELETE等方法。
https://www.jb51.net/article/212604.htm
代码搭建
数据库搭建
/*
Navicat Premium Data Transfer
Source Server : mysql
Source Server Type : MySQL
Source Server Version : 80026
Source Host : localhost:3306
Source Schema : cloud
Target Server Type : MySQL
Target Server Version : 80026
File Encoding : 65001
Date: 06/07/2022 20:04:04
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
`deptno` bigint(0) NOT NULL AUTO_INCREMENT,
`dname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`db_source` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`deptno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES (1, '开发部', 'cloud');
INSERT INTO `dept` VALUES (2, '人事部', 'cloud');
INSERT INTO `dept` VALUES (3, '算法部', 'cloud');
INSERT INTO `dept` VALUES (4, '市场部', 'cloud');
INSERT INTO `dept` VALUES (5, '运维部', 'cloud');
SET FOREIGN_KEY_CHECKS = 1;
创建Maven父项目,并编写pom.xml
(1)配置打包方式
<!--打包方式 pom-->
<packaging>pom</packaging>
(2)完整的父项目pom配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SpringCloudT</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>SpringCloud-api</module>
<module>SpringCloud-provider-dept-8001</module>
<module>SpringCloud-consumer-dept-80</module>
</modules>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<junit.version>4.12</junit.version>
<lombok.version>1.16.10</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.8</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
spring-cloud-dependencies这个依赖的版本要与Spring Boot的版本相对应!
建立子Module
注:同样以Maven形式创建。
配置SpringCloud-api module,用来存放实体类
pom.xml导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloudT</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SpringCloud-api</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
编写Dept.class
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true) //链式写法开启
public class Dept implements Serializable {
private long deptno;
private String dname;
private String db_source;
}
配置SpringCloud-provider-dept-8001 module,服务提供方
pom.xml 导入实体类
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloudT</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SpringCloude-provider-dept-9001</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--导入我们刚刚写的springclou-api,这样我们才可以调用到里面的实体类-->
<dependency>
<groupId>org.example</groupId>
<artifactId>SpringCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
application.yaml
server:
port: 8001
mybatis:
type-aliases-package: com.wjc.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 111111
DeptMapper.interface
import com.wjc.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface DeptMapper {
List<Dept> queryDeptList();
Dept queryDeptById(long id);
int addDept(Dept dept);
int updateDept(Dept dept);
int deleteDept(int id);
}
DeptMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个对应的Mapper接口-->
<mapper namespace="com.wjc.mapper.DeptMapper">
<!--增加一个-->
<insert id="addDept" parameterType="Dept">
insert into dept(dname, db_source)
values (#{dname}, #{db_source})
</insert>
<!--根据id删除一个-->
<delete id="deleteDept" parameterType="int">
delete from dept where deptno = #{deptno}
</delete>
<!--更新-->
<update id="updateDept" parameterType="Dept">
update dept
set dname = #{dname},db_source = #{db_source}
where deptno= #{deptno}
</update>
<!--根据id查询,返回一个-->
<select id="queryDeptById" resultType="Dept">
select * from dept
where deptno = #{deptno}
</select>
<!--查询全部-->
<select id="queryDeptList" resultType="Dept">
SELECT * from dept
</select>
</mapper>
service层省略
DeptController.class
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/dept")
public class DeptController {
@Resource
private DeptService deptService;
@GetMapping("/list")
public List<Dept> queryDeptList(){
List<Dept> depts = deptService.queryDeptList();
for (Dept dept : depts) {
System.out.println(dept);
}
return depts;
}
@GetMapping("/get/{id}")
public Dept get(@PathVariable("id") long id){
return deptService.queryDeptById(id);
}
@PostMapping("/add")
public Integer addDept(Dept dept){
return deptService.addDept(dept);
}
}
注意:Post可以用来读写数据,写入数据必须用Post,因为使用GET进行提交不安全,而只读可以用GET。
启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//@MapperScan("com.wjc.mapper") //配置扫描mapper接口包,动态实现mapper接口注入到spring容器中 取代以前的ssm xml配置
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class, args);
}
}
测试
配置SpringCloud-consumer-dept-80 module,服务消费者
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloudT</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SpringCloud-consumer-dept-80</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>SpringCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
编写配置类ConfigBean
a、由于Spring Cloud是基于HTTP的REST方式进行调用,所以我们这里需要使用到一个类RestTemplate,其可以提供多种便捷访问远程http服务的方法,简单的Restful服务模板。
b、但是RestTemplate并没有注入到Spring中,所以才需要我们自己编写配置类注册到Spring中。
application.yaml开放端口
server:
port: 80
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean {
//@Configuration -- spring applicationContext.xml
//配置负载均衡实现RestTemplate
// IRule
// RoundRobinRule 轮询
// RandomRule 随机
// AvailabilityFilteringRule : 会先过滤掉,跳闸,访问故障的服务~,对剩下的进行轮询~
// RetryRule : 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内进行,重试
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
编写DeptConsumerController控制类
注意:我们这个springcloud-consumer-dept-80是一个消费者项目,所以不存在service和dao,该项目只需要进行调用请求即可。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class ConsumerController {
/**
* 理解:消费者,不应该有service层~
* RestTemplate .... 供我们直接调用就可以了! 注册到Spring中
* (地址:url, 实体:Map ,Class<T> responseType)
* <p>
* 提供多种便捷访问远程http服务的方法,简单的Restful服务模板~
*/
@Autowired
private RestTemplate restTemplate;
/**
* 服务提供方地址前缀
* <p>
* Ribbon:我们这里的地址,应该是一个变量,通过服务名来访问
*/
private static final String REST_URL_PREFIX = "http://localhost:8001";
//private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
/**
* 消费方添加部门信息
* @param dept
* @return
*/
@RequestMapping("/consumer/dept/add")
public Integer add(Dept dept) {
// postForObject(服务提供方地址(接口),参数实体,返回类型.class)
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Integer.class);
}
/**
* 消费方根据id查询部门信息
* @param id
* @return
*/
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
// getForObject(服务提供方地址(接口),返回类型.class)
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
/**
* 消费方查询部门信息列表
* @return
*/
@RequestMapping("/consumer/dept/list")
public List<Dept> list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}
}
主启动类
@SpringBootApplication
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
测试