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. Sublime Text3 离线安装Package Control并使用GBK编码 --转自https://blog.csdn.net/swhard/article/details/78930371

    1.关闭Sublime Text 3,去https://github.com/wbond/package_control/releases下载一个zip包,我下载的是 2.将包内的顶层文件夹解压至C: ...

  2. delphi 各版本的特性

    delphi 各新版本特性收集 Delphi XE6新增了一些特性并增强了原有的功能,主要有以下几个方面:   IDE(整合开发环境)   Internet XML(扩展标记语言) Compiler( ...

  3. C#读写Excel实践笔记

    使用第三类包:NPOI 介绍 Github地址:https://github.com/tonyqus/npoi,Java POI项目的.NET版. 通过它可以在没有安装Office软件的情况下,快速的 ...

  4. JavaScript问题——在浏览器中每一个元素都有一个offsetParent属性,这个属性是什么?

    原文链接http://www.cnblogs.com/zcjnever/archive/2011/04/21/2023133.html Javascript中的offsetParent属性 支持的浏览 ...

  5. ubuntu16.04上vue环境搭建

    $ sudo apt-get install python-software-properties $ curl -sL https://deb.nodesource.com/setup_8.x | ...

  6. PROC IMPORT 选项

    GETNAMES=YES;导入源文件字段名作为SAS数据集的字段名MIXED=NO;若某一列中包含数值型和字符型变量,将数值型按照缺省值处理.若选的是YES则是将数值型转换成字符型存储,默认为NOSC ...

  7. Redis深入学习笔记(五)Redis阻塞原因

    在实际使用Redis中,有时会碰到客户端timeout异常,或者没有可用连接异常等等异常,总结大概有如下原因: 内部阻塞原因: 1)大对象存取. 2)Fork阻塞. 3)Aof刷盘阻塞(距离上次刷盘大 ...

  8. postgre索引

    1.创建一般索引 单字段索引: CREATE INDEX index_name ON table_name (field1); 联合索引: CREATE INDEX index_name ON tab ...

  9. UI自动化之元素定位(xpath、css)

    很早之前就已经写过自动化了,不过点着功能久了就会容易忘记元素定位,尤其是xpath和css定位,所以就花点时间做下总结收集. xpath有两种定位: 一.绝对路径(不推荐使用,除非已经使用了所有方式仍 ...

  10. 【HP-UNIX】修改HP-UNIX主机名称

    原文链接:https://blog.csdn.net/lantianbaiyunbj/article/details/53434537 HP-UX修改主机IP地址 方法一 1.set_parms ho ...