1.创建用户中心微服务
用户搜索到自己心仪的商品,接下来就要去购买,但是购买必须先登录。所以接下来我们编写用户中心,实现用户的登录和注册功能。
用户中心的提供的服务:
用户的注册
用户登录
这里我们暂时先实现基本的:注册和登录
功能。
因为用户中心的服务其它微服务也会调用,因此这里我们做聚合。
leyou-user:父工程,包含2个子工程:
leyou-user-interface:实体及接口
leyou-user-service:业务和服务
(1)创建父module
(2)创建leyou-user-interface
在leyou-user下,创建module:
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"> <parent> <artifactId>leyou-userartifactId> <groupId>lucky.leyou.usergroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <groupId>lucky.leyou.usergroupId> <artifactId>leyou-user-interfaceartifactId> project>
(3)创建leyou-user-service
注意:创建leyou-user-service过程与创建leyou-user-interface过程类似
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"> <parent> <artifactId>leyou-userartifactId> <groupId>lucky.leyou.usergroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <groupId>lucky.leyou.usergroupId> <artifactId>leyou-user-serviceartifactId> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-jdbcartifactId> dependency> <dependency> <groupId>org.mybatis.spring.bootgroupId> <artifactId>mybatis-spring-boot-starterartifactId> dependency> <dependency> <groupId>tk.mybatisgroupId> <artifactId>mapper-spring-boot-starterartifactId> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> dependency> <dependency> <groupId>lucky.leyou.usergroupId> <artifactId>leyou-user-interfaceartifactId> <version>1.0-SNAPSHOTversion> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> dependency> dependencies> project>
启动器类:
package lucky.leyou; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import tk.mybatis.spring.annotation.MapperScan; @SpringBootApplication @EnableDiscoveryClient @MapperScan("lucky.leyou.user.mapper") public class LeyouUserApplication { public static void main(String[] args) { SpringApplication.run(LeyouUserApplication.class, args); } }
配置:
server: port: 8085 spring: application: name: user-service datasource: url: jdbc:mysql://localhost:3306/leyou?serverTimezOne=UTC&useSSL=false username: root password: plj824 driver-class-name: com.mysql.jdbc.Driver eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: lease-renewal-interval-in-seconds: 5 lease-expiration-duration-in-seconds: 15 mybatis: type-aliases-package: lucky.leyou.user.domain
父工程leyou-user的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"> <parent> <artifactId>leyouartifactId> <groupId>lucky.leyou.parentgroupId> <version>1.0-SNAPSHOTversion> parent> <modelVersion>4.0.0modelVersion> <groupId>lucky.leyou.usergroupId> <artifactId>leyou-userartifactId> <packaging>pompackaging> <modules> <module>leyou-user-interfacemodule> <module>leyou-user-servicemodule> modules> project>
(4)添加网关路由
我们修改leyou-gateway
,添加路由规则,对leyou-user-service
进行路由:
server:
port: 10010
spring:
application:
name: leyou-gateway
eureka:
client:
registry-fetch-interval-seconds: 5
service-url:
defaultZone: http://localhost:10086/eureka
zuul:
prefix: /api # 路由路径前缀
routes:
item-service: /item/** # 商品微服务的映射路径
search-service: /search/** #搜索微服务
user-service: /user/** #用户微服务
2.后台功能准备
(1)数据结构
CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(32) NOT NULL COMMENT '密码,加密存储', `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号', `created` datetime NOT NULL COMMENT '创建时间', `salt` varchar(32) NOT NULL COMMENT '密码加密的salt值', PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='用户表';
数据结构比较简单,因为根据用户名查询的频率较高,所以我们给用户名创建了索引
(2)基本代码
<1>实体类
需要用到实体类注解,pom文件中添加依赖
<dependencies> <dependency> <groupId>javax.persistencegroupId> <artifactId>persistence-apiartifactId> <version>1.0version> dependency> <dependency> <groupId>com.fasterxml.jackson.coregroupId> <artifactId>jackson-databindartifactId> <version>2.9.6version> dependency> dependencies>
实体类:
package lucky.leyou.user.domain; import com.fasterxml.jackson.annotation.JsonIgnore; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import java.util.Date; @Table(name = "tb_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username;// 用户名 @JsonIgnore private String password;// 密码 private String phone;// 电话 private Date created;// 创建时间 @JsonIgnore //对象序列化为json字符串时,忽略该属性 private String salt;// 密码的盐值 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phOne= phone; } public Date getCreated() { return created; } public void setCreated(Date created) { this.created = created; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } }
注意:为了安全考虑。这里对password和salt添加了注解@JsonIgnore,这样在json序列化时,就不会把password和salt返回
<2>mapper
package lucky.leyou.user.mapper; import lucky.leyou.user.domain.User; import tk.mybatis.mapper.common.Mapper; public interface UserMapper extends Mapper{ }
<3>Service
package lucky.leyou.user.service; import lucky.leyou.user.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserMapper userMapper; }
<4>Controller
package lucky.leyou.user.controller; import lucky.leyou.user.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class UserController { @Autowired private UserService userService; }
3.数据验证功能
(1)接口说明
实现用户数据的校验,主要包括对:手机号、用户名的唯一性校验。
接口路径:
GET /check/{data}/{type}
参数说明:
返回布尔类型结果:
true:可用
false:不可用
状态码:
200:校验成功
400:参数有误
500:服务器内部异常
(2)controller
因为有了接口,我们可以不关心页面,所有需要的东西都一清二楚:
请求方式:GET
请求路径:/check/{param}/{type}
请求参数:param,type
返回结果:true或false
/** * 校验数据是否可用 * @param data 占位符参数 * @param type 占位符参数 * @return */ @GetMapping("check/{data}/{type}") public ResponseEntitycheckUserData(@PathVariable("data") String data, @PathVariable(value = "type") Integer type) { Boolean boo = this.userService.checkUser(data, type); if (boo == null) { //参数不合法 return ResponseEntity.badRequest().build(); } return ResponseEntity.ok(boo); }
(3)service
/** * 实现用户数据的校验,主要包括对:手机号、用户名的唯一性校验。 * @param data 占位符参数 * @param type * @return */ public Boolean checkUser(String data, Integer type) { User record = new User(); switch (type) { case 1: record.setUsername(data); break; case 2: record.setPhone(data); break; default: return null; } return this.userMapper.selectCount(record) == 0; }
(4)测试
<1>启动nginx
<2>开启微服务
我们在数据库插入一条假数据:
然后在浏览器调用接口,测试:
不经过网关,直接通过端口访问
经过网关,通过Nginx代理直接通过端口访问