1.   学习计划

1、sso注册功能实现

2、sso登录功能实现

3、通过token获得用户信息

Ajax跨域请求(jsonp)

2.   Sso系统工程搭建

需要创建一个sso服务工程,可以参考e3-manager创建。

e3-sso(pom聚合工程)

|--e3-sso-interface(jar)

|--e3-sso-Service(war)

e3-sso-web

3.   服务接口实现

3.1. 检查数据是否可用

3.1.1.    功能分析

请求的url:/user/check/{param}/{type}

参数:从url中取参数

1、String param(要校验的数据)

2、Integer type(校验的数据类型)

响应的数据:json数据。e3Result,封装的数据校验的结果true:成功false:失败。

业务逻辑:

1、从tb_user表中查询数据

2、查询条件根据参数动态生成。

3、判断查询结果,如果查询到数据返回false。

4、如果没有返回true。

5、使用e3Result包装,并返回。

3.1.2.    Dao层

从tb_user表查询。可以使用逆向工程。

3.1.3.    Service

参数:

1、要校验的数据:String param

2、数据类型:int type(1、2、3分别代表username、phone、email)

返回值:e3Result

@Service
public class RegisterServiceImpl implements RegisterService{ @Autowired
private TbUserMapper userMapper; @Override
public E3Result checkData(String param, int type) {
// 1、从tb_user表中查询数据
TbUserExample example = new TbUserExample();
Criteria criteria = example.createCriteria();
// 2、查询条件根据参数动态生成。
//1、2、3分别代表username、phone、email
if (type == 1) {
criteria.andUsernameEqualTo(param);
} else if (type == 2) {
criteria.andPhoneEqualTo(param);
} else if (type == 3) {
criteria.andEmailEqualTo(param);
} else {
return E3Result.build(400, "非法的参数");
}
//执行查询
List<TbUser> list = userMapper.selectByExample(example);
// 3、判断查询结果,如果查询到数据返回false。
if (list == null || list.size() == 0) {
// 4、如果没有返回true。
return E3Result.ok(true);
}
// 5、使用E3Result包装,并返回。
return E3Result.ok(false); } }

发布服务

 <dubbo:service interface="cn.e3mall.sso.service.RegisterService" ref="registerServiceImpl"  timeout="600000"/>

3.1.4.    表现层

需要在e3-sso-web中实现。

Controller

请求的url:/user/check/{param}/{type}

参数:从url中取参数1、String param(要校验的数据)2、Integer type(校验的数据类型)

响应的数据:json数据。e3Result,封装的数据校验的结果true:成功false:失败。

@Controller
public class RegitsterController { @Autowired
private RegisterService registerService; @RequestMapping("/user/check/{param}/{type}")
@ResponseBody
public E3Result checkData(@PathVariable String param,@PathVariable Integer type){
E3Result e3Result=registerService.checkData(param, type);
return e3Result;
} }

引用服务

    <dubbo:reference interface="cn.e3mall.sso.service.RegisterService" id="registerService" />

3.2. 用户注册

3.2.1.    功能分析

请求的url:/user/register

参数:表单的数据:username、password、phone

返回值:json数据。e3Result

接收参数:使用TbUser对象接收。

请求的方法:post

业务逻辑:

1、使用TbUser接收提交的请求。

2、补全TbUser其他属性。

3、密码要进行MD5加密。

4、把用户信息插入到数据库中。

5、返回e3Result。

3.2.1.    Dao层

可以使用逆向工程。

3.2.2.    Service层

参数:TbUser

返回值:E3Result

    @Override
public E3Result createUser(TbUser user) {
// 1、使用TbUser接收提交的请求。 if (StringUtils.isBlank(user.getUsername())) {
return E3Result.build(400, "用户名不能为空");
}
if (StringUtils.isBlank(user.getPassword())) {
return E3Result.build(400, "密码不能为空");
}
//校验数据是否可用
E3Result result = checkData(user.getUsername(), 1);
if (!(boolean) result.getData()) {
return E3Result.build(400, "此用户名已经被使用");
}
//校验电话是否可以
if (StringUtils.isNotBlank(user.getPhone())) {
result = checkData(user.getPhone(), 2);
if (!(boolean) result.getData()) {
return E3Result.build(400, "此手机号已经被使用");
}
}// 2、补全TbUser其他属性。
user.setCreated(new Date());
user.setUpdated(new Date());
// 3、密码要进行MD5加密。
String md5Pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
user.setPassword(md5Pass);
// 4、把用户信息插入到数据库中。
userMapper.insert(user);
// 5、返回E3Result。
return E3Result.ok(); }

发布服务

3.2.4.    表现层

引用服务。

Controller:

请求的url:/user/register

参数:表单的数据:username、password、phone、email

返回值:json数据。e3Result

接收参数:使用TbUser对象接收。

请求的方法:post

    @RequestMapping("/user/register")
public E3Result createUser(TbUser tbuser){
E3Result e3=registerService.createUser(tbuser);
return e3;
}

33. 用户登录

3.3.1.    功能分析

请求的url:/user/login

请求的方法:POST

参数:username、password,表单提交的数据。可以使用方法的形参接收。

返回值:json数据,使用e3Result包含一个token。

业务逻辑:

登录的业务流程:

登录的处理流程:

1、登录页面提交用户名密码。

2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。

3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。

4、使用String类型保存Session信息。可以使用“前缀:token”为key

5、设置key的过期时间。模拟Session的过期时间。一般半个小时。

6、把token写入cookie中。

7、Cookie需要跨域。例如www.e3.com\sso.e3.com\order.e3.com,可以使用工具类。

8、Cookie的有效期。关闭浏览器失效。

9、登录成功。

3.3.2.    Dao层

查询tb_user表。单表查询。可以使用逆向工程。

3.3.3.    Service层

参数:

1、用户名:String username

2、密码:String password

返回值:e3Result,包装token。

业务逻辑:

1、判断用户名密码是否正确。

2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。

3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。

4、使用String类型保存Session信息。可以使用“前缀:token”为key

5、设置key的过期时间。模拟Session的过期时间。一般半个小时。

6、返回e3Result包装token。

@Service
public class UserServiceImpl implements UserService{ @Autowired
private TbUserMapper userMapper;
@Autowired
private JedisClient jedisClient;
@Value("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE; @Override
public E3Result login(String username, String password) {
// 1、判断用户名密码是否正确。
TbUserExample example = new TbUserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo(username);
//查询用户信息
List<TbUser> list = userMapper.selectByExample(example);
if (list == null || list.size() == 0) {
return E3Result.build(400, "用户名或密码错误");
}
TbUser user = list.get(0);
//校验密码
if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {
return E3Result.build(400, "用户名或密码错误");
}
// 2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。
String token = UUID.randomUUID().toString();
// 3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。
// 4、使用String类型保存Session信息。可以使用“前缀:token”为key
user.setPassword(null);
jedisClient.set("SESSION:" +token, JsonUtils.objectToJson(user));
// 5、设置key的过期时间。模拟Session的过期时间。一般半个小时。
jedisClient.expire("SESSION:"+ token, SESSION_EXPIRE);
// 6、返回e3Result包装token。
return E3Result.ok(token);
} }

发布服务

3.3.4.    表现层

引用服务

Controller

请求的url:/user/login

请求的方法:POST

参数:username、password,表单提交的数据。可以使用方法的形参接收。

HttpServletRequest、HttpServletResponse

返回值:json数据,使用e3Result包含一个token。

业务逻辑:

1、接收两个参数。

2、调用Service进行登录。

3、从返回结果中取token,写入cookie。Cookie要跨域。

4、响应数据。Json数据。e3Result,其中包含Token。

    @Autowired
private UserService userService;
@Value("${TOKEN_KEY}")
private String TOKEN_KEY; @RequestMapping("/user/login")
@ResponseBody
public E3Result login(String username,String password,HttpServletRequest request,HttpServletResponse response){
E3Result e3Result = userService.login(username, password);
if(e3Result.getStatus()==200){
String token=e3Result.getData().toString();
CookieUtils.setCookie(request, response, TOKEN_KEY, token);
}
return e3Result;
}

3.4. 通过token查询用户信息

3.4.1.    功能分析

请求的url:/user/token/{token}

参数:String token需要从url中取。

返回值:json数据。使用e3Result包装Tbuser对象。

业务逻辑:

1、从url中取参数。

2、根据token查询redis。

3、如果查询不到数据。返回用户已经过期。

4、如果查询到数据,说明用户已经登录。

5、需要重置key的过期时间。

6、把json数据转换成TbUser对象,然后使用e3Result包装并返回。

3.4.2.    Dao层

使用JedisClient对象。

3.4.3.    Service层

参数:String token

返回值:e3Result

@Service
public class TokenServiceImpl implements TokenService { @Autowired
private JedisClient jedisClient;
@Value("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE; @Override
public E3Result getUserByToken(String token) {
//根据token到redis中取用户信息
String json = jedisClient.get("SESSION:" + token);
//取不到用户信息,登录已经过期,返回登录过期
if (StringUtils.isBlank(json)) {
return E3Result.build(201, "用户登录已经过期");
}
//取到用户信息更新token的过期时间
jedisClient.expire("SESSION:" + token, SESSION_EXPIRE);
//返回结果,E3Result其中包含TbUser对象
TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);
return E3Result.ok(user);
} }

3.4.3.    表现层

请求的url:/user/token/{token}

参数:String token需要从url中取。

返回值:json数据。使用e3Result包装Tbuser对象。

@Controller
public class TokenController { @Autowired
private TokenService tokenService; @RequestMapping("/user/token/{token}")
@ResponseBody
public E3Result getUserByToken(@PathVariable String token) {
E3Result result = tokenService.getUserByToken(token);
return result;
} }

5.   登录注册页面整合首页

5.1. 首页跳转到登录、注册页面

5.2. 首页展示用户名

1、当用户登录成功后,在cookie中有token信息。

2、从cookie中取token根据token查询用户信息。

3、把用户名展示到首页。

方案一:在Controller中取cookie中的token数据,调用sso服务查询用户信息。

方案二:当页面加载完成后使用js取token的数据,使用ajax请求查询用户信息。

问题:服务接口在sso系统中。Sso.e3.com(localhost:8089),在首页显示用户名称,首页的域名是www.e3.com(localhost:8083),使用ajax请求跨域了。

Js不可以跨域请求数据。

什么是跨域:

1、域名不同

2、域名相同端口不同。

解决js的跨域问题可以使用jsonp。

Jsonp不是新技术,跨域的解决方案。使用js的特性绕过跨域请求。Js可以跨域加载js文件。

5.3. Jsonp原理

5.4. Json实现

5.4.1.    客户端

使用jQuery。

5.4.2.    服务端

1、接收callback参数,取回调的js的方法名。

2、业务逻辑处理。

3、响应结果,拼接一个js语句。

SSM商城项目(十一)的更多相关文章

  1. SSM商城项目(一)

    1. 学习计划 1.电商行业的背景. 2.宜立方商城介绍 3.宜立方商城的系统架构 a) 功能介绍 b) 架构讲解 4.工程搭建-后台工程 a) 使用maven搭建工程 b) 使用maven的tomc ...

  2. SSM商城项目(四)

    1. 学习计划 1.图片服务器 2.图片服务器安装 3.图片服务器的使用 4.图片上传功能 5.富文本编辑器的使用方法 6.商品添加功能实现 2. 图片服务器 1.存储空间可扩展. 2.提供一个统一的 ...

  3. SSM商城项目(二)

    1. 学习计划 1.将工程改造为基于SOA架构 2.商品列表查询功能实现. 2. 将工程改造为SOA架构 2.1. 分析 由于商城是基于soa的架构,表现层和服务层是不同的工程.所以要实现商品列表查询 ...

  4. SSM商城项目(八)

    1.   学习计划 1.solr集群搭建 2.使用solrj管理solr集群 3.把搜索功能切换到集群版 4.添加商品同步到索引库 2.   什么是SolrCloud SolrCloud(solr 云 ...

  5. SSM商城项目(五)

    1.   学习计划 1.前台系统搭建 2.商城首页展示 3.Cms系统的实现 a)         内容分类管理 b)         内容管理 4.前台内容动态展示 2.   商城首页展示 2.1. ...

  6. SSM商城项目(十三)

    1.   学习计划 1.订单系统 2.提交订单 3.MyCAT 2.   订单系统 2.1. 功能分析 1.在购物车页面点击“去结算”按钮跳转到订单确认页面. a)         展示商品列表 b) ...

  7. SSM商城项目(十二)

    1.   学习计划 1.购物车实现 2.未登录状态下使用购物车 3.登录状态下使用购物车 2.   购物车的实现 2.1. 功能分析 1.购物车是一个独立的表现层工程. 2.添加购物车不要求登录.可以 ...

  8. SSM商城项目(十)

    1.   学习计划 1.使用freemarker实现网页静态化 a)Freemarker的使用方法 b)Freemarker模板的语法 c)Freemarker整合springmvc 2.Active ...

  9. SSM商城项目(九)

    1.   学习计划 1.Activemq整合springMQ的应用场景 2.添加商品同步索引库 3.商品详情页面动态展示 4.展示详情页面使用缓存 2.   Activemq整合spring 2.1. ...

随机推荐

  1. Unity外包团队:U3D与UE我选哪个好?请别再问这种问题了!

    原本预先决定的两家VR游戏公司采访,思熊和星为棋,并没有发现什么共性之初.结果在采访之后却意外发现,两家的经历有着非常相似的地方.他们都是来自于开发游戏所用的引擎的原开发商,比如思熊的主力来自Epic ...

  2. python基础知识10---算法

    一.递归 程序本身自己调用自己称之为递归,类似于俄罗斯套娃,体现在代码中:用户执行最外(N)层函数,最外侧调用N-1层函数,N-1层函数调用N-2层函数... 利用函数编写如下数列: 斐波那契数列指的 ...

  3. HTTP Server to Client Communication

    1. Client browser short polling The most simple solution, client use Ajax to sends a request to the ...

  4. matlab画台风轨迹图小tip

    <写在前面> 关于台风轨迹图,这次由于作业需要就画了一幅轨迹图,参考原图选自论文: LIU Zenghong, XU Jianping, SUN Chaohui, WU Xiaofen. ...

  5. php正则讲解 及与 js的正则比较

    正则:用于检索字符串的规则: js正则: var reg=/规则/ reg是一个对象,在浏览器下: 所以研究他的属性和方法 属性: global是修饰符,代表全局检索 g ignorecase 忽略大 ...

  6. 使用SimpleDateFormat类来实现时间跟字符串的转化

    使用Date和SimpleDateFormat类表示时间 1.Date类 需要处理日期和时间的相关数据时可以使用 java.util 包中的 Date 类,这个类最主要的作用就是获取当前时间.下面看看 ...

  7. 知识点:Mysql 索引优化实战(3)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 索引原理知识回顾 索引的性 ...

  8. DOM事件类

    1.DOM中的事件级别 DOM0: element.onclick = function(){} DOM1: 没有与事件相关的设计 DOM2: element.addEventListener('cl ...

  9. Oracle不能连接故障排除[TNS-12541: TNS: 无监听程序]

    1. 情况:Oracle安装后使用的好好的,放假关机后重新开机居然发现不能正常连线,客户报错:TNS-12541: TNS: 无监听程序 2. 检查:         1. 服务器上Oracle启动正 ...

  10. C#;DataTable添加列;DataTable转List泛型集合;List泛型集合转DataTable泛型集合;

    给DataTable添加列 string sql = "select * from cgpmb order by code"; DataTable dt = Bobole.Data ...