1. Environmental construction
1.1 architecture analysis
- Registry: Nacos
- Gateway: Gateway
- Backend infrastructure: ssm
- Front end: Vue + SPA
- Axios(request.js)
1.2 database environment
1.2. 1 student database
#Student database CREATE DATABASE nacos_ssm_student; USE nacos_ssm_student; CREATE TABLE tb_city( c_id VARCHAR(32) PRIMARY KEY COMMENT 'city ID', city_name VARCHAR(20) COMMENT 'City name' , parent_id VARCHAR(32) COMMENT 'father ID' ); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320000','Jiangsu Province','0'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140000','Shanxi Province','0'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130000','Hebei Province','0'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320100','Nanjing City','320000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320102','Xuanwu District','320100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320103','Baixia District','320100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321300','Suqian City','320000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321322','Shuyang County','321300'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321323','Siyang County','321300'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140100','Taiyuan City','140000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140106','Yingze District','140100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140108','Jiancaoping District ','140100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140800','Yuncheng City','140000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140823','Wenxi County','140800'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140828','summer county','140800'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130100','Shijiazhuang City ','130000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130127','Gaoyi County','130100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130185','Luquan ','130100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131000','Langfang City','130000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131003','Guangyang District','131000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131022','Gu'an County','131000'); CREATE TABLE `tb_student` ( `s_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'student ID', `sname` VARCHAR(50) DEFAULT NULL COMMENT 'full name', `age` INT(11) DEFAULT NULL COMMENT 'Age', `birthday` DATETIME DEFAULT NULL COMMENT 'birthday', `gender` CHAR(1) DEFAULT NULL COMMENT 'Gender', `c_id` INT DEFAULT NULL, `city_ids` VARCHAR(32) DEFAULT NULL COMMENT 'City: 320000,321300,321322' ); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (1,'Zhao San 33',21,'2001-01-17 00:00:00','1',1,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (2,'Qian Si 444',1900,'2001-05-16 00:00:00','1',2,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (3,'Sun wu56',189,'2022-03-15 00:00:00','0',1,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (4,'Zhang San',20,'2020-12-21 00:00:00','0',2,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (5,'xxx',18,'2020-12-21 00:00:00','0',2,'140000,140800,140823'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (6,'123',18,'2020-11-01 00:00:00','0',3,'130000,130100,130127'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (7,'xx',18,'2020-11-02 00:00:00','0',1,'130000,131000,131003');
1.2. 2 user database
# User database CREATE DATABASE nacos_ssm_user; USE nacos_ssm_user; CREATE TABLE `tb_user` ( `u_id` VARCHAR(32) PRIMARY KEY NOT NULL COMMENT 'User number', `user_name` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT 'user name', `password` VARCHAR(32) DEFAULT NULL COMMENT 'password', `gender` BIT(1) DEFAULT NULL COMMENT 'Gender,1 Indicates male, 0 indicates female', `image` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT 'Avatar picture' ); INSERT INTO `tb_user`(`u_id`,`user_name`,`password`,`gender`,`image`) VALUES ('u001','jack','1234',1,'1.jpg'); INSERT INTO `tb_user`(`u_id`,`user_name`,`password`,`gender`,`image`) VALUES ('u002','rose','1234',0,'2.jpg'); INSERT INTO `tb_user`(`u_id`,`user_name`,`password`,`gender`,`image`) VALUES ('u003','tom','1234',1,'3.jpg');
1.2. 3 class database
# Class database CREATE DATABASE nacos_ssm_classes; USE nacos_ssm_classes; CREATE TABLE `tb_teacher` ( `tid` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `tname` VARCHAR(50) DEFAULT NULL COMMENT 'Teacher name', `type` INT(11) DEFAULT NULL COMMENT 'Teacher type: 1.Instructor, 2.Assistant teacher, 3.Counselor teacher' ); INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (1,'Miss Liang Tong',1); INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (2,'Mr. Ma Kun',2); INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (3,'Miss Zhong Yan',3); INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (4,'Mr. Yuan Xinxin',1); INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (5,'Mr. Ren Linda',2); INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (6,'Miss Wang Shanshan',3); CREATE TABLE `tb_class` ( `cid` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `cname` VARCHAR(50) DEFAULT NULL COMMENT 'Class name', `teacher1_id` INT(11) DEFAULT NULL COMMENT 'Instructor', `teacher2_id` INT(11) DEFAULT NULL COMMENT 'Assistant teacher', `teacher3_id` INT(11) DEFAULT NULL COMMENT 'Counselor teacher' ); INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (1,'Java56',1,2,3); INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (2,'Java78',1,2,3); INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (3,'Java12',4,5,6); INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (4,'Java34',4,5,6);
1.2. 4 student database
#Student database CREATE DATABASE nacos_ssm_student; USE nacos_ssm_student; CREATE TABLE tb_city( c_id VARCHAR(32) PRIMARY KEY COMMENT 'city ID', city_name VARCHAR(20) COMMENT 'City name' , parent_id VARCHAR(32) COMMENT 'father ID' ); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320000','Jiangsu Province','0'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140000','Shanxi Province','0'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130000','Hebei Province','0'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320100','Nanjing City','320000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320102','Xuanwu District','320100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320103','Baixia District','320100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321300','Suqian City','320000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321322','Shuyang County','321300'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321323','Siyang County','321300'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140100','Taiyuan City','140000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140106','Yingze District','140100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140108','Jiancaoping District ','140100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140800','Yuncheng City','140000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140823','Wenxi County','140800'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140828','summer county','140800'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130100','Shijiazhuang City ','130000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130127','Gaoyi County','130100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130185','Luquan ','130100'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131000','Langfang City','130000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131003','Guangyang District','131000'); INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131022','Gu'an County','131000'); CREATE TABLE `tb_student` ( `s_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'student ID', `sname` VARCHAR(50) DEFAULT NULL COMMENT 'full name', `age` INT(11) DEFAULT NULL COMMENT 'Age', `birthday` DATETIME DEFAULT NULL COMMENT 'birthday', `gender` CHAR(1) DEFAULT NULL COMMENT 'Gender', `c_id` INT DEFAULT NULL, `city_ids` VARCHAR(32) DEFAULT NULL COMMENT 'City: 320000,321300,321322' ); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (1,'Zhao San 33',21,'2001-01-17 00:00:00','1',1,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (2,'Qian Si 444',1900,'2001-05-16 00:00:00','1',2,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (3,'Sun wu56',189,'2022-03-15 00:00:00','0',1,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (4,'Zhang San',20,'2020-12-21 00:00:00','0',2,'320000,321300,321322'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (5,'xxx',18,'2020-12-21 00:00:00','0',2,'140000,140800,140823'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (6,'123',18,'2020-11-01 00:00:00','0',3,'130000,130100,130127'); INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (7,'xx',18,'2020-11-02 00:00:00','0',1,'130000,131000,131003');
1.3 back end environment
1.3. 1 parent project
-
Steps:
- Step 1: create the project Nacos SSM student
- Step 2: add coordinates
-
Step 1: create a project
-
Step 2: add coordinates:
<!-- 1 determine spring boot Version of--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> </parent> <!--2 Determine version--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <spring-cloud-release.version>Hoxton.SR3</spring-cloud-release.version> <nacos.version>1.1.0</nacos.version> <alibaba.cloud.version>2.2.1.RELEASE</alibaba.cloud.version> <mybatis.starter.version>1.3.2</mybatis.starter.version> <mapper.starter.version>2.0.2</mapper.starter.version> <mysql.version>5.1.32</mysql.version> <pageHelper.starter.version>1.2.5</pageHelper.starter.version> <durid.starter.version>1.1.10</durid.starter.version> <swagger.version>2.7.0</swagger.version> <jwt.jjwt.version>0.9.0</jwt.jjwt.version> <jwt.joda.version>2.9.7</jwt.joda.version> <beanutils.version>1.9.3</beanutils.version> <student.version>1.0-SNAPSHOT</student.version> </properties> <!-- 3 Locked version--> <dependencyManagement> <dependencies> <!-- sprig cloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud-release.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--nacos --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>${nacos.version}</version> </dependency> <!--nacos cloud find --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <!--nacos cloud to configure --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <!-- mybatis starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.starter.version}</version> </dependency> <!-- currency Mapper starter --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>${mapper.starter.version}</version> </dependency> <!-- Paging assistant launcher --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>${pageHelper.starter.version}</version> </dependency> <!-- mysql drive --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!-- Druid Connection pool --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${durid.starter.version}</version> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency> <!--jwt--> <!--JavaBean Tool class for JavaBean Data encapsulation--> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>${beanutils.version}</version> </dependency> <!--jwt tool--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jwt.jjwt.version}</version> </dependency> <!--joda Time tool class --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>${jwt.joda.version}</version> </dependency> <!-- Custom item --> <dependency> <groupId>com.czxy</groupId> <artifactId>nacos-ssm-student-domain</artifactId> <version>${student.version}</version> </dependency> </dependencies> </dependencyManagement>
1.3.2 domain project
-
Steps:
- Step 1: create the project: Nacos SSM student domain
- Step 2: add pom
- Step 3: copy vo (BaseResult)
- Step 4: copy the JavaBean
-
Step 1: create the project: Nacos SSM student domain
-
Step 2: add pom
<dependencies> <!--jpa--> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--jackson--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </dependency> </dependencies>
-
Step 3: copy vo
package com.czxy.vo; import lombok.Getter; import java.util.HashMap; import java.util.Map; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Getter public class BaseResult<T> { //Success status code public static final int OK = 20000; //Failure status code public static final int ERROR = 0; //Return code private Integer code; //Return message private String message; //Store data private T data; //Other data private Map<String,Object> other = new HashMap<>(); public BaseResult() { } public BaseResult(Integer code, String message) { this.code = code; this.message = message; } public BaseResult(Integer code, String message, T data) { this.code = code; this.message = message; this.data = data; } /** * Shortcut successful BaseResult object * @param message * @return */ public static BaseResult ok(String message){ return new BaseResult(BaseResult.OK , message); } public static BaseResult ok(String message, Object data){ return new BaseResult(BaseResult.OK , message, data ); } /** * Shortcut failed BaseResult object * @param message * @return */ public static BaseResult error(String message){ return new BaseResult(BaseResult.ERROR , message); } /** * Custom data area * @param key * @param msg * @return */ public BaseResult append(String key , Object msg){ other.put(key , msg); return this; } }
-
Step 4: copy the JavaBean
-
City
package com.czxy.domain; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; /** * (TbCity)Entity class * * @author Uncle Tong */ @Table(name = "tb_city") @Data public class City implements Serializable { private static final long serialVersionUID = 660498290955870873L; /** * City ID */ @Id @Column(name = "c_id") private String cid; /** * City name */ @Column(name = "city_name") private String cityName; /** * Parent ID */ @Column(name = "parent_id") private String parentId; }
-
Classes
package com.czxy.domain; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Table(name = "tb_class") @Data public class Classes { @Id @Column(name = "cid") private Integer cid; @Column(name = "cname") private String cname; //Class name @Column(name = "teacher1_id") private Integer teacher1Id; //Instructor @Column(name = "teacher2_id") private Integer teacher2Id; //Assistant teacher @Column(name = "teacher3_id") private Integer teacher3Id; //Counselor teacher }
-
Course
package com.czxy.domain; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Table(name = "tb_course") @Data public class Course { @Id @Column(name = "c_id") private Integer cid; @Column(name = "cname") private String cname; @Column(name = "`desc`") private String desc; }
-
Student
package com.czxy.domain; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Table(name = "tb_student") @Data public class Student { @Id @Column(name = "s_id") private Integer sid; //Student ID @Column(name = "sname") private String sname; //full name @Column(name = "age") private Integer age; //Age @Column(name = "birthday") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date birthday; //birthday @Column(name = "gender") private String gender; //Gender @Column(name = "c_id") private Integer cid; //Class foreign key @Column(name = "city_ids") private String cityIds; //city private List<City> cityList; //Selected city @Transient private Classes classes; //Class object @Transient private Integer courseCount; //Number of courses selected @Transient private List<Course> courseList = new ArrayList<>(); //Course selection details @Transient private List<Integer> courseIds = new ArrayList(); //Course selection id }
-
Teacher
package com.czxy.domain; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Table(name = "tb_teacher") @Data public class Teacher { @Id @Column(name = "tid") private Integer tid; @Column(name = "tname") private String tname; //Teacher name @Column(name = "type") private Integer type; //Teacher type: 1 Instructor, 2 Assistant teacher, 3 Counselor teacher }
-
User
package com.czxy.domain; import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Table(name = "tb_user") @Data public class User { @Id @Column(name = "u_id") private String uid; @Column(name = "user_name") private String userName; private String password; private Integer gender; private String image; } /* CREATE TABLE `tb_user` ( `u_id` VARCHAR(32) PRIMARY KEY NOT NULL COMMENT 'User number ', `user_name` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT 'User name ', `password` VARCHAR(32) DEFAULT NULL COMMENT 'Password ', `gender` BIT(1) DEFAULT NULL COMMENT 'Gender, 1 for male, 0 for female ', `image` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT ''Avatar picture' ); */
-
1.3. 3 gateway: 10010
-
Steps:
-
Step 1: create a project, the Nacos SSM student gateway
-
Step 2: add coordinates
-
Step 3: configure the file application yml
-
Step 4: copy the global cross domain configuration class GlobalGatewayCorsConfig
-
Step 5: start the GatewayApplication class
-
-
Step 1: create a project, the Nacos SSM student gateway
-
Step 2: add coordinates
<dependencies> <!-- gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- nacos Service discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--JavaBean Tool class for JavaBean Data encapsulation--> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> </dependency> <!--jwt tool--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency> <!--joda Time tool class --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> </dependency> </dependencies>
-
Step 3: Profile
#Port number server: port: 10010 spring: application: name: student-gateway cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #nacos service address gateway: discovery: locator: enabled: true #Turn on the function of service registration and discovery, automatically create a router, and forward the request path starting with the service name to the corresponding service lowerCaseServiceId: true #Configure the service name on the request path to lowercase
-
Step 4: copy the global cross domain configuration class
package com.czxy.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Configuration public class GlobalGatewayCorsConfig { @Bean public WebFilter corsFilter2() { return (ServerWebExchange ctx, WebFilterChain chain) -> { ServerHttpRequest request = ctx.getRequest(); if (CorsUtils.isCorsRequest(request)) { HttpHeaders requestHeaders = request.getHeaders(); ServerHttpResponse response = ctx.getResponse(); HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod(); HttpHeaders headers = response.getHeaders(); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin()); headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders()); if (requestMethod != null) { headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name()); } headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*"); if (request.getMethod() == HttpMethod.OPTIONS) { response.setStatusCode(HttpStatus.OK); return Mono.empty(); } } return chain.filter(ctx); }; } }
-
Step 5: start class
package com.czxy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @SpringBootApplication @EnableDiscoveryClient public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } }
1.3. 4 Student Services: 9000
-
Steps:
- Step 1: create a project: Nacos SSM student service student
- Step 2: add pom
- Step 3: write yml
- Step 4: write the startup class, StudentServiceApplication
- Step 5: copy Swagger configuration class, Swagger2ConfigurationV3
-
Step 1: create a project: Nacos SSM student service student
-
Step 2: add pom
<dependencies> <!--web Start dependence--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- nacos client --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> </dependency> <!-- nacos Service discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- mybatis starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- currency Mapper starter --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> </dependency> <!-- Paging assistant launcher --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> </dependency> <!-- mysql drive --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- Druid Connection pool --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> <!-- feign Remote call --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Custom item --> <dependency> <groupId>com.czxy</groupId> <artifactId>nacos-ssm-student-domain</artifactId> </dependency> </dependencies>
-
Step 3: write yml
#Port number server: port: 9000 spring: application: name: student-service #service name datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/nacos_ssm_student?useUnicode=true&characterEncoding=utf8 username: root password: 1234 druid: #druid connection pool configuration initial-size: 1 #Initialize connection pool size min-idle: 1 #Minimum number of connections max-active: 20 #maximum connection test-on-borrow: true #Verification when obtaining connections will affect performance cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #nacos service address sentinel: transport: dashboard: 127.0.0.1:8080
-
Step 4: write the startup class
package com.czxy.student; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @SpringBootApplication @EnableDiscoveryClient public class StudentServiceApplication { public static void main(String[] args) { SpringApplication.run(StudentServiceApplication.class, args ); } }
-
Step 5: copy Swagger2ConfigurationV3 configuration class
package com.czxy.student.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList; import java.util.List; /** * Swagger2 Configuration class, * Access path: swagger UI html * Automatic registration: * Location: Resources / meta-inf / spring factories * Content: * org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ * com.czxy.config.Swagger2Configuration */ @Configuration @EnableSwagger2 public class Swagger2ConfigurationV3 { @Bean public Docket createRestApi() { // 1 determine the Swagger version of the document Docket docket = new Docket(DocumentationType.SWAGGER_2); // 2. Setting api basic information docket.apiInfo(apiInfo()); // 3. Set custom loading path docket = docket.select() .apis(RequestHandlerSelectors.basePackage("com.czxy")) .paths(PathSelectors.any()) .build(); //4 set permissions docket.securitySchemes(securitySchemes()); docket.securityContexts(securityContexts()); return docket; } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("API") .description("be based on swagger Interface documentation") .contact(new Contact("Liang Tong","http://www.javaliang.com","liangtong@itcast.cn")) .version("1.0") .build(); } private List<ApiKey> securitySchemes() { List<ApiKey> list = new ArrayList<>(); // Name is the parameter name. Keyname is the keyname displayed on the page. Name is used in swagger authentication list.add(new ApiKey("Authorization", "Authorization", "header")); return list; } private List<SecurityContext> securityContexts() { List<SecurityContext> list = new ArrayList<>(); list.add(SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("^(?!auth).*$")) .build()); return list; } private List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; List<SecurityReference> list = new ArrayList(); list.add(new SecurityReference("Authorization", authorizationScopes)); return list; } }
1.4 front end environment
1.4. 1 create project
vue create nacos-student-spa
1.4. 2 install axios
cnpm install axios --save
1.4. 3 extraction axios
-
Installation dependency
npm i element-ui --save
-
Create tool Src / utils / request js
import axios from 'axios' import { MessageBox, Message } from 'element-ui' // Method 1: set basic path // axios.defaults.baseURL='http://localhost:10010/api' // Method 2: create an axios instance and set the basic path const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000 // request timeout }) // request interceptor service.interceptors.request.use( config => { // Append token in request header let token = localStorage.getItem('token') if (token) { config.headers.Authorization = token } return config }, error => { // do something with request error console.log(error) // for debug return Promise.reject(error) } ) // response interceptor service.interceptors.response.use( response => { const res = response.data // if the custom code is not 20000, it is judged as an error. if (res.code !== 20000) { Message({ message: res.message || 'Error', type: 'error', duration: 5 * 1000 }) // ajax exception prompt information (path information, data) console.info(response.config, response.data ) return Promise.reject(new Error(res.message || 'Error')) } else { return res } }, error => { console.log('err' + error) // for debug if(error.response.status == 401) { MessageBox.confirm(error.response.data, 'Login again confirmation box', { confirmButtonText: 'Login again', cancelButtonText: 'cancel', type: 'warning' }).then(() => { // Delete token localStorage.removeItem('token') location.reload() }) } else { Message({ message: error.message, type: 'error', duration: 5 * 1000 }) } return Promise.reject(error) } ) export default service
-
Using the tool, create Src / API / student. XML js
// Import tool request js import axios from '@/utils/request.js' // Writing function method export function condition(studentPage, studentVo) { return axios.post(`/student-service/student/condition/${studentPage.pageSize}/${studentPage.pageNum}`, studentVo) }
1.4. 4 start
npm run serve
1.4. 5 access
http://localhost:8080/
1.4. 6. Modify the entry page
<template> <div> <router-link to="/classes_list">Class management</router-link> | <router-link to="/student_list">Student management</router-link> | <router-link to="/user_register">register</router-link> | <router-link to="/user_login">Sign in</router-link> | <hr> <!-- View display area --> <router-view/> </div> </template> <script> export default { } </script> <style> </style>
1.4. 7 Optimization: Copy Editor configuration file
-
Create file editorconfig
# editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false
2. Student management
2.1 query all backend:
2.1. 1 demand
- Query all students, including conditional query and paging query
2.1. 2 interface
POST http://localhost:10010/student-service/student/condition/3/1 { "code": 20000, "message": "query was successful", "data": { "records": [ { "sid": 1, "sname": "Zhao San 33", "age": 21, "birthday": "2001-01-17", "gender": "1", "cid": 1, "cityIds": "320000,321300,321322", "cityList": null, "classes": null, "courseCount": null, "courseList": [], "courseIds": [] }, ... ] }
2.1. 3 back end implementation
-
Step 1: copy configuration class (Swagger configuration class)
-
Step 2: create a conditional query encapsulation class: StudentVo
-
Step 3: write Mapper
-
Step 4: write the service interface and implementation class
-
Step 5: write controller
-
Step 6: Test
-
Step 1: copy configuration class (Swagger configuration class)
-
Step 2: create a conditional query encapsulation class: StudentVo
package com.czxy.student.vo; import lombok.Data; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Data public class StudentVo { private String cid; //class private String sname; //full name private String startAge; //Starting age private String endAge; //End age }
-
Step 3: write Mapper
-
Step 4: write a service
-
Interface
-
Implementation class
-
-
Step 5: write controller
-
Step 6: Test
http://localhost:9000/student/condition/3/1 http://localhost:10010/student-service/student/condition/3/1
2.2 query: front end
2.2. 1 query all
-
Requirements: display student list
-
Steps:
- Step 1: determine the access path
- Step 2: write a route
- Step 3: query all
-
Step 1: determine the access path
-
Step 2: write a route
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path: '/student_list', name: 'Student list', component: () => import('../views/StudentList.vue') } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
-
Step 3: query all
<template> <div> <router-link to="/student_add">Add student</router-link> <!-- Query list --> <table id="tid" border="1" width="800"> <tr> <td>student ID</td> <td>class ID</td> <td>Student name</td> <td>Age</td> <td>birthday</td> <td>Gender</td> <td>operation</td> </tr> <tr v-for="(student,index) in pageInfo.list" :key="index"> <td>{{student.sid}}</td> <td>{{student.cid}}</td> <td>{{student.sname}}</td> <td>{{student.age}}</td> <td>{{student.birthday}}</td> <td>{{student.gender == 1 ? "male" : "female"}}</td> <td> <a>modify</a> <a>delete</a> </td> </tr> </table> </div> </template> <script> import {condition} from '@/api/student.js' export default { data() { return { pageInfo: { //Paging object pageSize: 2, pageNum: 1 }, studentVo: { //Condition form object cid: '' }, } }, mounted() { // Query all this.conditionFn() }, methods: { async conditionFn() { let { data } = await condition(this.pageInfo,this.studentVo) console.info(data) this.pageInfo = data }, }, } </script> <style> </style>
2.2. 2 condition all
-
Requirements:
-
step
- Step 1: add a conditional query form
- Step 2: improve the conditionFn function
-
Step 1: add a conditional query form
<!-- query criteria --> <table> <tr> <td>class</td> <td> <select v-model="studentVo.cid"> <option value="">--Select class--</option> <option value="1">Java12 class</option> <option value="2">Java34 class</option> <option value="3">Java56 class</option> </select> </td> <td>full name:</td> <td> <input type="text" placeholder="Please enter your name" v-model="studentVo.sname" size="10"> </td> <td>Age:</td> <td> <input type="text" placeholder="Please enter the starting age" v-model="studentVo.startAge" size="10"> -- <input type="text" placeholder="Please enter the end age" v-model="studentVo.endAge" size="10"> </td> <td><input type="button" value="query" @click="conditionFn(1)"></td> </tr> </table>
-
Step 2: improve the conditionFn function
async conditionFn(pageNum) { if(pageNum) { this.pageInfo.pageNum = pageNum } let { data } = await condition(this.pageInfo,this.studentVo) console.info(data) this.pageInfo = data },
2.2. 3 page all
-
Requirements:
-
step
- Step 1: add paging information
- Step 2: write jump function
-
Step 1: add paging information
<!-- Paging bar --> <div id="pageId"> each page <select v-model="pageInfo.pageSize" @change="conditionFn(1)"> <option value="1">1</option> <option value="2">2</option> <option value="5">5</option> <option value="10">10</option> </select>Article, <a href="#" v-for="index in pageInfo.pages" :key="index" @click.prevent="conditionFn(index)" >{{index}}</a> ,Jump to page <input type="text" v-model="pageInfo.pageNum" size="5" @keydown.enter="go" />page </div>
-
Step 2: write jump function
go() { if(parseInt(this.pageInfo.pageNum) == this.pageInfo.pageNum) { this.conditionFn() } },