首先是父工程
使用Maven创建出父工程flightMicroservice
父工程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>com.onlyk</groupId>
<artifactId>flightMicroservice</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>flightMicroservice</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<druid.version>1.1.10</druid.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.13.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
子工程flight-common
使用SpringCloud创建项目flight-common
选择Lombok
导入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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.onlyk</groupId>
<artifactId>flightMicroservice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>flight-common</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--ribbon相关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--引入Feign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类不需要加载数据源
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
导入工具类
BuildTree.java
package com.onlyk.flightcommon.utils;
import com.onlyk.flightcommon.vo.TreeVo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author only老K 我为自己代言
* @create 2020-03-29 17:13
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
public class BuildTree {
/**
* 默认-1为顶级节点
* @param nodes
* @param <T>
* @return
*/
public static <T> TreeVo<T> build(List<TreeVo<T>> nodes) {
if (nodes == null) {
return null;
}
List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();
for (TreeVo<T> children : nodes) {
String pid = children.getParentId();
if (pid == null || "-1".equals(pid)) {
topNodes.add(children);
continue;
}
for (TreeVo<T> parent : nodes) {
String id = parent.getId();
if (id != null && id.equals(pid)) {
parent.getChildren().add(children);
children.setHasParent(true);
parent.setChildren(true);
continue;
}
}
}
TreeVo<T> root = new TreeVo<T>();
if (topNodes.size() == 1) {
root = topNodes.get(0);
} else {
root.setId("000");
root.setParentId("-1");
root.setHasParent(false);
root.setChildren(true);
root.setChecked(true);
root.setChildren(topNodes);
root.setText("顶级节点");
Map<String, Object> state = new HashMap<>(16);
state.put("opened", true);
root.setState(state);
}
return root;
}
/**
* 指定idparam为顶级节点
* @param nodes
* @param idParam
* @param <T>
* @return
*/
public static <T> List<TreeVo<T>> buildList(List<TreeVo<T>> nodes, String idParam) {
if (nodes == null) {
return null;
}
List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();
for (TreeVo<T> children : nodes) {
String pid = children.getParentId();
if (pid == null || idParam.equals(pid)) {
topNodes.add(children);
continue;
}
for (TreeVo<T> parent : nodes) {
String id = parent.getId();
if (id != null && id.equals(pid)) {
parent.getChildren().add(children);
children.setHasParent(true);
parent.setChildren(true);
continue;
}
}
}
return topNodes;
}
}
CodeMsg.java
package com.onlyk.flightcommon.result;
/**
* @author only老K 我为自己代言
* @create 2020-03-29 17:13
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
public class CodeMsg {
private int code;
private String msg;
//通用的错误码
public static CodeMsg SUCCESS = new CodeMsg(0, "success");
public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务端异常");
public static CodeMsg BIND_ERROR = new CodeMsg(500101, "参数校验异常:%s");
//登录模块 5002XX
public static CodeMsg SESSION_ERROR = new CodeMsg(500210, "Session不存在或者已经失效");
public static CodeMsg PASSWORD_EMPTY = new CodeMsg(500211, "登录密码不能为空");
public static CodeMsg MOBILE_EMPTY = new CodeMsg(500212, "手机号不能为空");
public static CodeMsg MOBILE_ERROR = new CodeMsg(500213, "手机号格式错误");
public static CodeMsg MOBILE_NOT_EXIST = new CodeMsg(500214, "手机号不存在");
public static CodeMsg PASSWORD_ERROR = new CodeMsg(500215, "密码错误");
//权限模块 5003XX
//数据字典 5004XX
public static CodeMsg ORDER_NOT_EXIST = new CodeMsg(500400, "订单不存在");
//秒杀模块 5005XX
public static CodeMsg MIAO_SHA_OVER = new CodeMsg(500500, "商品已经秒杀完毕");
public static CodeMsg REPEATE_MIAOSHA = new CodeMsg(500501, "不能重复秒杀");
private CodeMsg( ) {
}
private CodeMsg( int code,String msg ) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public CodeMsg fillArgs(Object... args) {
int code = this.code;
String message = String.format(this.msg, args);
return new CodeMsg(code, message);
}
@Override
public String toString() {
return "CodeMsg [code=" + code + ", msg=" + msg + "]";
}
}
Result.java
package com.onlyk.flightcommon.result;
/**
* @author only老K 我为自己代言
* @create 2020-03-29 17:13
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
public class Result<T> {
private int code;
private String msg;
private T data;
public Result() {
}
/**
* 成功时候的调用
* */
public static <T> Result<T> success(T data){
return new Result<T>(data);
}
/**
* 失败时候的调用
* */
public static <T> Result<T> error(CodeMsg codeMsg){
return new Result<T>(codeMsg);
}
private Result(T data) {
this.data = data;
}
private Result(int code, String msg) {
this.code = code;
this.msg = msg;
}
private Result(CodeMsg codeMsg) {
if(codeMsg != null) {
this.code = codeMsg.getCode();
this.msg = codeMsg.getMsg();
}
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
TreeVo.java
package com.onlyk.flightcommon.vo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author only老K 我为自己代言
* @create 2020-03-29 17:14
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
public class TreeVo<T> {
/**
* 节点ID
*/
private String id;
/**
* 显示节点文本
*/
private String text;
/**
* 节点状态,open closed
*/
private Map<String, Object> state;
/**
* 节点是否被选中 true false
*/
private boolean checked = false;
/**
* 节点属性
*/
private Map<String, Object> attributes;
/**
* 节点的子节点
*/
private List<TreeVo<T>> children = new ArrayList<TreeVo<T>>();
/**
* 父ID
*/
private String parentId;
/**
* 是否有父节点
*/
private boolean hasParent = false;
/**
* 是否有子节点
*/
private boolean hasChildren = false;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Map<String, Object> getState() {
return state;
}
public void setState(Map<String, Object> state) {
this.state = state;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public Map<String, Object> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
}
public List<TreeVo<T>> getChildren() {
return children;
}
public void setChildren(List<TreeVo<T>> children) {
this.children = children;
}
public boolean isHasParent() {
return hasParent;
}
public void setHasParent(boolean isParent) {
this.hasParent = isParent;
}
public boolean isHasChildren() {
return hasChildren;
}
public void setChildren(boolean isChildren) {
this.hasChildren = isChildren;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public TreeVo(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
List<TreeVo<T>> children, boolean isParent, boolean isChildren, String parentID) {
super();
this.id = id;
this.text = text;
this.state = state;
this.checked = checked;
this.attributes = attributes;
this.children = children;
this.hasParent = isParent;
this.hasChildren = isChildren;
this.parentId = parentID;
}
public TreeVo() {
super();
}
}
子工程flight-eureka-2001
使用SpringCloud创建flight-eureka-2001
选择Lombok
导入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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.onlyk</groupId>
<artifactId>flightMicroservice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>flight-eureka-2001</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</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>
</project>
yml文件配置(集群版本)
# register-with-eurekas 是否相互注册
# fetch-registry 是否同步信息,默认是true
---
server:
port: 2001
context-path: /
eureka:
instance:
hostname: eureka2001.onlyk.com
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
spring:
profiles: eureka2001
---
server:
port: 2002
context-path: /
eureka:
instance:
hostname: eureka2002.onlyk.com
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
spring:
profiles: eureka2002
---
server:
port: 2003
context-path: /
eureka:
instance:
hostname: eureka2003.onlyk.com
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
spring:
profiles: eureka2003
启动类配置
@EnableEurekaServer
@SpringBootApplication
子工程flight-provider-1001
使用SpringCloud创建flight-provider-1001
选择Lombok
导入pom
#留下父亲工程组织信息,以及自己的项目名
<properties>
<java.version>1.8</java.version>
<mysql.version>5.1.44</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.zking</groupId>
<artifactId>flight-common</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-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!--添加注册中心Eureka相关配置-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--Hystrix相关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- actuator监控引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
<include>*.xml</include>
<include>*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<dependencies>
<!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<configuration>
<overwrite>true</overwrite>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
yml配置
---
server:
port: 1001
context-path: /
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123
jpa:
hibernate:
ddl-auto: update
show-sql: true
application:
name: microservice-flight
profiles: provider-hystrix-1001
thymeleaf:
prefix: classpath:/templates
eureka:
instance:
hostname: localhost
appname: microservice-flight
instance-id: microservice-flight:1001
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka2001.onlyk.com:2001/eureka/,http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
info:
groupId: com.onlyk
artifactId: microservice-flight-provider-hystrix-1001
version: 1.0-SNAPSHOT
userName: http://onlyk.com
phone: 123456
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1500
---
server:
port: 1005
context-path: /
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123
jpa:
hibernate:
ddl-auto: update
show-sql: true
application:
name: microservice-flight
profiles: provider-hystrix-1005
eureka:
instance:
hostname: localhost
appname: microservice-flight
instance-id: microservice-flight:1005
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka2001.onlyk.com:2001/eureka/,http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
info:
groupId: com.onlyk
artifactId: microservice-flight-provider-hystrix-1005
version: 1.0-SNAPSHOT
userName: http://onlyk.com
phone: 123456
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1500
---
server:
port: 1006
context-path: /
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123
jpa:
hibernate:
ddl-auto: update
show-sql: true
application:
name: microservice-flight
profiles: provider-hystrix-1006
eureka:
instance:
hostname: localhost
appname: microservice-flight
instance-id: microservice-flight:1006
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka2001.javaxl.com:2001/eureka/,http://eureka2002.javaxl.com:2002/eureka/,http://eureka2003.javaxl.com:2003/eureka/
info:
groupId: com.onlyk
artifactId: microservice-flight-provider-hystrix-1006
version: 1.0-SNAPSHOT
userName: http://onlyk.com
phone: 123456
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1500
启动类配置
# MapperScan 扫码当前包的mapper
# EnableEurekaClient Eureka的客户端
# EnableTransactionManagement 事务
@MapperScan("com.zking.flightprovider1001.mapper")
@EnableTransactionManagement
@EnableEurekaClient
@SpringBootApplication
由于上面使用到了Mybatis所以有Maven逆向生成代码这篇博客里面有哦
使用逆向生成工具完成(把逆向生成的entity放入到common中去)
子工程flight-consumer-80
使用SpringCloud创建flight-consumer-80
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.onlyk</groupId>
<artifactId>flightMicroservice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>flight-consumer-80</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.onlyk</groupId>
<artifactId>flight-common</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-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml配置
# eurake配置、feign与Hystrix整合、ribbon与server:
port: 80
context-path: /
eureka:
client:
service-url:
defaultZone: http://eureka2001.onlyk.com:2001/eureka/,http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
register-with-eureka: false
feign:
hystrix:
enabled: true
ribbon:
ReadTimeout: 10000
ConnectTimeout: 9000
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
启动类配置
@ComponentScan(basePackages = {"com.onlyk.flightcommon","com.onlyk.flightconsumer80"})//扫描公共模块 用了哪里的就扫描哪里的
@EnableEurekaClient
//在当前微服务(消费者80)调用了其他微服务(生产者1001)
@EnableFeignClients(value = "com.onlyk.*.*")
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
SpringCloudConfig配置类(主要做负载均衡及其策略配置)
package com.onlyk.flightconsumer80.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RetryRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* @author only老K 我为自己代言
* @create 2020-03-30 11:54
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
public class SpringCloudConfig {
@LoadBalanced // 引入ribbon负载均衡
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
/**
* 自定义调用规则(服务提供者掉线后不再调用,解决轮询问题)
* @return
*/
@Bean
public IRule myRule(){
return new RetryRule();
// return new RandomRule();
}
}
子工程flight-zuul-3001
使用SpringCloud创建flight-zuul-3001
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.onlyk</groupId>
<artifactId>flightMicroservice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>flight-zuul-3001</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.onlyk</groupId>
<artifactId>flight-common</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-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- actuator监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- hystrix容错 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml配置
server:
port: 3001
context-path: /
spring:
application:
name: microservice-zuul
eureka:
instance:
instance-id: microservice-zuul:3001
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka2001.onlyk.com:2001/eureka/,http://eureka2002.onlyk.com:2002/eureka/,http://eureka2003.onlyk.com:2003/eureka/
info:
groupId: com.onlyk.testSpringcloud
artifactId: microservice-zuul-3001
version: 1.0-SNAPSHOT
userName: http://onlyk.com
phone: 123456
zuul:
routes:
studentServer.serviceId: microservice-flight
studentServer.path: /flightServer/**
ignored-services: "*"
prefix: /onlyk
启动类配置
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableZuulProxy
过滤器(启动屏蔽内部微服务访问的作用)
AccessFilter.java
package com.onlyk.flightzuul3001.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @author only老K 我为自己代言
* @create 2020-03-30 12:05
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@Component
public class AccessFilter extends ZuulFilter {
Logger logger= Logger.getLogger(AccessFilter.class);
/**
* 判断该过滤器是否要被执行
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体执行逻辑
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String parameter = request.getParameter("accessToken");
logger.info(request.getRequestURL().toString()+" 请求访问");
if(parameter==null){
logger.error("accessToken为空!");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("{\"result\":\"accessToken is empty!\"}");
return null;
}
// token判断逻辑
logger.info(request.getRequestURL().toString()+" 请求成功");
return null;
}
/**
* 过滤器的类型 这里用pre,代表会再请求被路由之前执行
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过滤器的执行顺序
*/
@Override
public int filterOrder() {
return 0;
}
}
TestFilter.java
package com.onlyk.flightzuul3001.config;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author only老K 我为自己代言
* @create 2020-03-30 12:06
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@Component
@WebFilter(urlPatterns = "/*", filterName = "ajaxCORS")
public class TestFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("过滤器初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.printf("过滤器实现");
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
// Access-Control-Allow-Origin就是我们需要设置的域名
// Access-Control-Allow-Headers跨域允许包含的头。
// Access-Control-Allow-Methods是允许的请求方式
httpResponse.addHeader("Access-Control-Allow-Origin", "*");// *,任何域名
httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("过滤器销毁了");
}
}
最终配置类
ZuulConfig.java
package com.onlyk.flightzuul3001.config;
import com.onlyk.flightzuul3001.filter.AccessFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author only老K 我为自己代言
* @create 2020-03-30 12:05
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@Configuration
public class ZuulConfig {
@Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}
}
环境搭建完毕,写代码测试即可
provider-1001
DataDictMapper
List<DataDict> list(Map map);
DataDictMapper.xml
<select id="list" resultType="com.onlyk.flightcommon.entity.DataDict" parameterType="java.util.Map" >
select
<include refid="Base_Column_List" />
from t_springcloud_data_dict
<where>
<if test="description != null" >
description like #{description}
</if>
</where>
</select>
package com.onlyk.flightprovider1001.server;
import com.onlyk.flightcommon.entity.DataDict;
import java.util.List;
/**
* @author only老K 我为自己代言
* @create 2020-04-03 15:19
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
public interface DataDictService {
int deleteByPrimaryKey(Integer id);
int insert(DataDict record);
int insertSelective(DataDict record);
DataDict selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(DataDict record);
int updateByPrimaryKey(DataDict record);
public List<DataDict> list();
}
package com.onlyk.flightprovider1001.server.impl;
import com.onlyk.flightcommon.entity.DataDict;
import com.onlyk.flightprovider1001.mapper.DataDictMapper;
import com.onlyk.flightprovider1001.server.DataDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author only老K 我为自己代言
* @create 2020-04-03 15:20
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@Service
public class DataDictServiceImpl implements DataDictService {
@Autowired
private DataDictMapper dataDictMapper;
@Override
public int deleteByPrimaryKey(Integer id) {
return dataDictMapper.deleteByPrimaryKey(id);
}
@Override
public int insert(DataDict record) {
return dataDictMapper.insert(record);
}
@Override
public int insertSelective(DataDict record) {
return dataDictMapper.insertSelective(record);
}
@Override
public DataDict selectByPrimaryKey(Integer id) {
return dataDictMapper.selectByPrimaryKey(id);
}
@Override
public int updateByPrimaryKeySelective(DataDict record) {
return dataDictMapper.updateByPrimaryKeySelective(record);
}
@Override
public int updateByPrimaryKey(DataDict record) {
return dataDictMapper.updateByPrimaryKey(record);
}
@Override
public List<DataDict> list() {
return dataDictMapper.list(null);
}
}
package com.onlyk.flightprovider1001.controller;
import com.onlyk.flightcommon.entity.DataDict;
import com.onlyk.flightcommon.result.Result;
import com.onlyk.flightprovider1001.server.DataDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author only老K 我为自己代言
* @create 2020-04-03 15:23
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@RestController
@RequestMapping("/dataDict")
public class DataDictController {
@Autowired
private DataDictService dataDictService;
@RequestMapping("/list")
public Result<List<DataDict>> list(){
try {
System.out.println("112523");
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
List<DataDict> list = dataDictService.list();
return Result.success(list);
}
}
common
package com.onlyk.flightcommon.server;
import com.onlyk.flightcommon.entity.DataDict;
import com.onlyk.flightcommon.result.CodeMsg;
import com.onlyk.flightcommon.result.Result;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author only老K 我为自己代言
* @create 2020-04-03 8:29
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@Component
public class DataDictClientFallbackFactory implements FallbackFactory<DataDictClientService> {
@Override
public DataDictClientService create(Throwable throwable) {
return new DataDictClientService() {
@Override
public Result<List<DataDict>> list() {
return Result.error(CodeMsg.SERVER_ERROR);
}
};
}
}
package com.onlyk.flightcommon.server;
import com.onlyk.flightcommon.entity.DataDict;
import com.onlyk.flightcommon.result.Result;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
/**
* @author only老K 我为自己代言
* @create 2020-04-03 8:28
* @blogaddress https://blog.csdn.net/weixin_44255950
*/
@FeignClient(value="MICROSERVICE-FLIGHT",fallbackFactory = DataDictClientFallbackFactory.class)
public interface DataDictClientService {
@GetMapping(value="/dataDict/list")
public Result<List<DataDict>> list();
}
启动测试
启动顺序(注册中心–1001–80–zuul)80启动不启动没有关系