Easymall项目分布式拆分整合(七)

                            Easymall项目分布式拆分整合(七)


目录

                            Easymall项目分布式拆分整合(七)

一.Easymall分布式项目结构

二.用户搭建(最基础的六部)

1.创建一个quickstart的maven工程(src/main/resources)

2.pom继承parent,依赖common

3.后台user系统需要的其他依赖

4.application.properties文件

5.启动类(MapperScan)

6.nginx和hosts文件

1.nginx配置

2.hoste文件配置

三.用户系统的功能

一.注册用户用户名校验

1.接口文件

2.UserController

3.UserService

二.注册表单数据的提交

1.接口文件

2.UserController

3.UserService

 

三.实现注册方法与前台系统的整合

1.调用结构

2.前台的结构搭建

3.导入一个UserController类

3.创建一个UserService等待逻辑编写

1.用户名称校验

2.打开controller对应的交互逻辑代码注册user

四.用户的登录逻辑

一.接口方法,处理登录的校验

1.登录的用户系统校验逻辑

2.接口文件

3.编写用户登录逻辑

1.UserController类

2.RedisCumUtils中添加一个超时方法

3.UserService(redisUtil)类

4.js页面发起ajax请求获取user登录的状态信息(携带cookie的值)

1.接口文件

2.UserController

3.UserService


一.Easymall分布式项目结构

二.用户搭建(最基础的六部)

1.创建一个quickstart的maven工程(src/main/resources)

2.pom继承parent,依赖common

3.后台user系统需要的其他依赖

  <dependencies>
  <dependency>
  	<groupId>cn..tedu</groupId>
  	<artifactId>springboot-common-easymall</artifactId>
  	<version>0.0.1-SNAPSHOT</version>
  </dependency>
  	<dependency>
  		<groupId>org.springframework.boot</groupId>
  		<artifactId>spring-boot-starter-jdbc</artifactId>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  	</dependency>
  	<dependency>
  		<groupId>org.mybatis.spring.boot</groupId>
       	<artifactId>mybatis-spring-boot-starter</artifactId>	
  	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

4.application.properties文件

  • 端口8093
  • datasource
  • mybatis
  • redis
server.port=8093

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///easydb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.password=root
spring.datasource.username=root

mybatis.configuration.mapUnderscoreToCamelCase=true
mybatis.mapperLocations=classpath:mapper/*.xml
mybatis.typeAliasesPackage=com.jt.common.pojo

redis.nodes=10.42.60.249:6379
redis.maxTotal=200
redis.maxIdle=8
redis.minIdle=3

 

5.启动类(MapperScan)

  • 扫描接口mapper的包
  • UserMapper(重新导入User的包名,common)
  • UserMapper.xml(修改namespce对应新的接口全路径)
  • 启动类
package com.jt;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.jt.user.mapper")
public class StarterUser {
	
	public static void main(String[] args) {
		SpringApplication.run(StarterUser.class, args);
	}
}

6.nginx和hosts文件

1.nginx配置

	#User服务器
	server {
		listen       80;
		server_name  user.easymall.com;
		
			
		proxy_set_header X-Forwarded-Host $host;
		proxy_set_header X-Forwarded-Server $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		
		location / {
		       proxy_pass http://127.0.0.1:8093;
		       proxy_connect_timeout 600;
		       proxy_read_timeout 600;
		}
	}

2.hoste文件配置

127.0.0.1

user.easymall.com

三.用户系统的功能

.注册用户用户名校验

1.接口文件

请求地址

user.easymall.com/user/checkUserName/{userName}

请求方式

GET

请求参数

路径传参的String userName

返回数据

存在返回1不可用,不存在返回0表示可用

2.UserController

public class UserController {
	@Autowired
	private UserService userService;
	//接收前台的请求,返回数据库用户名可用还是不可用
	@RequestMapping("checkUserName/{userName}")
	public Integer checkUserName(@PathVariable String userName){
		Integer exist=userService.checkUserName(userName);
		return exist;
	}

3.UserService

	@Autowired
	private UserMapper userMapper;
	public Integer checkUserName(String userName) {
		return userMapper.queryName(userName);
	}

 

二.注册表单数据的提交

1.接口文件

请求地址

user.easymall.com/user/save

请求方式

post

请求参数

User user对象接收,缺少的属性type,默认0,userId使用UUID解决

返回数据

1.SysResult的结构的数据,需要前端调用之后解析数据,可以满足返回数据的丰富性(既可以传递结果,也可以传递消息)

2.新增成功失败返回1/0

2.UserController

	@RequestMapping("save")
	public Integer saveUser(User user){
		try{
			userService.saveUser(user);
			return 1;
		}catch(Exception e){
			e.printStackTrace();
			return 0;
		}
	}

3.UserService

	public void saveUser(User user) {
		//user的id,type,password的加密
		user.setUserId(UUID.randomUUID().toString());
		user.setUserPassword(MD5Util.md5(user.getUserPassword()));
		user.setUserType(0);
		userMapper.insertUser(user);
	}

 

三.实现注册方法与前台系统的整合

1.调用结构

2.前台的结构搭建

将easymall单体项目中的UserController(包含了与页面的交互逻辑),粘贴到web前端系统

3.导入一个UserController类

@Controller
public class UserController {
	@Autowired
	private UserService userService;
	//ajax查询用户是否名称存在
	@RequestMapping(value="user_ajax/checkUserName"
			,method=RequestMethod.POST)
	@ResponseBody
	public SysResult checkUserName(String userName){
		int exist=userService.queryName(userName);
		//数据库如果存在,返回1,数据库如果不存在返回0
		return SysResult.build(exist, "ok", null);
	}
	
	@RequestMapping(value="/user_ajax/regist"
			,method=RequestMethod.POST)
	@ResponseBody
	public SysResult saveUser(User user){
		try{
			//业务层调用,插入表格数据
			userService.saveUser(user);
			return SysResult.build(1, null, null);
		}catch(Exception e){
			e.printStackTrace();
			return SysResult.build(0, null, null);
		}
	}
	

3.创建一个UserService等待逻辑编写

1.用户名称校验

private static final String url="http://user.easymall.com/user/";
	//注入httpClient
	@Autowired
	private HttpClientService client;
	public int queryName(String userName) {
		//按照接口文件进行调用和传参和数据的接收
		String userUrl=url+"checkUserName/"+userName;
		try{
			String exist=client.doGet(userUrl);
			return Integer.parseInt(exist);
		}catch(Exception e){
			e.printStackTrace();
			return 0;
		}
	}

2.打开controller对应的交互逻辑代码注册user

编写service中saveUser方法 

   public void saveUser(User user) {
        //按照注册接口调用user系统
        String userUrl=url+"save";
        try{
            //生成参数
            Map<String,Object> param=new HashMap<String,Object>();
            param.put("userName", user.getUserName());
            param.put("userPassword", user.getUserPassword());
            param.put("userEmail", user.getUserEmail());
            param.put("userNickname", user.getUserNickname());
            client.doPost(userUrl,param);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

四.用户的登录逻辑

用户登录逻辑,需要处理session共享问题,将用户信息,存储在redis中将key作为数据返回页面时,放到cookie中,只要cookie中key,后续访问逻辑www.easymall.com系统时,都会携带这个key,从而可以处理获取redis的数据使用.

一.接口方法,处理登录的校验

1.登录的用户系统校验逻辑

  • 用户名密码的校验(where userName password是否存在数据)
  • 如果不存在,按照接口返回不存在的数据
  • 如果存在,将查询到的user作为整体数据存放到redis key值计算逻辑(公式:"EM_TICKET"+currentTime+userId),value值就是userJson字符串
  • 将ticket的key值返回给前台

2.接口文件

请求地址

user.easymall.com/user/login

请求的参数

User user对象接收,自动封装了userName和Password

请求方式

get/post

返回数据

将存储在redis中的当前ticket的key值返回,存储到redis中的数据表示一个用户的登录状态(userJson),所以不能是永久数据,设置超时(做后续的逻辑,同一个用户最多登录一次)

 

3.编写用户登录逻辑

1.UserController类

//验证登录的用户名密码是否正确
	@RequestMapping("login")
	public String doLogin(User user){
		String ticket=userService.doLogin(user);
		//成功登录返回redis的key,失败返回""
		return ticket;
	}

2.RedisCumUtils中添加一个超时方法

	//封装一个带有超时逻辑的add方法
		public void addOrUpdateExpire(String key,String value,Integer seconds){
			ShardedJedis jedis = pool.getResource();
			try{
				jedis.setex(key, seconds, value);
			}catch(Exception e){
				//异常处理逻辑
			}finally{
				pool.returnBrokenResource(jedis);
			}
		}

3.UserService(redisUtil)类

@Autowired
	private RedisCumUtils redis;
	public String doLogin(User user) {
		//查询一下数据库数据,是否存在userExist
		//处理用户密码加密
		user.setUserPassword(MD5Util.md5(user.getUserPassword()));
		User exist=userMapper.selectExist(user);
		try{
			if(exist==null){//登录失败
				return "";
			}else{//表示成功,存储在redis返回key值
				String ticket=MD5Util.md5("EM_TICKET"+System.currentTimeMillis()
				+exist.getUserId());
				//准备value值,mapper转化user为json字符串
				String userJson=MapperUtils.MP.writeValueAsString(exist);
				//set数据到redis供后续逻辑使用
				redis.addOrUpdateExpire(ticket, userJson, 60*30);
				//验证最多一个用户登录,顶替登录逻辑 
				//TODO
				return ticket;
			}	
		}catch(Exception e){
			e.printStackTrace();
			return "";
		}
	}

4.js页面发起ajax请求获取user登录的状态信息(携带cookie的值)

将jsp文件中head.jsp的js代码修改访问的域名,从原有的sso.jt.com换成user.jt.com

1.接口文件

请求地址

user.easymall.com/user/query/{ticket}

请求方式

get

请求参数

redis中的key值,ticket路径接参

String callback

返回数据

通过对callback的判断,实现返回数据的封装,

if(callback==null)说明不是jsonp请求,返回syResult的json字符串

if(callback!=null)说明是jsonp请求,返回

callback(+sysResultJson+)

sysResult的status==200表示成功,201表示失败

2.UserController

//校验登录状态,查询redis数据
	@RequestMapping("query/{ticket}")
	public String checkTicket(@PathVariable String ticket
			,String callback){
		try{
			//走到redis校验数据
			String userJson=userService.queryTicket(ticket);
			//封装返回的json数据,SysResult
			SysResult result=null;
			if(StringUtils.isNotEmpty(userJson)){//登录状态正常
				result=SysResult.build(200, "", userJson);
			}else{
				result=SysResult.build(201, "", null);
			}
			//将result解析成json等待返回使用
			String resultJson=MapperUtils.MP.writeValueAsString(result);
			//判断请求需要的数据格式,callback
			if(callback==null){
				return resultJson;//作为json字符串返回
			}else{
				return callback+"("+resultJson+")";//jsonp格式返回
			}
		}catch(Exception e){
			return "";
		}	
	}

3.UserService

	public String queryTicket(String ticket) {
		//TODO 超时时间延长--续租
		
		return redis.query(ticket);
	}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值