1 注册功能的实现
登录和注册的功能都放到单点登录系统中完成,供其他系统调用。
资源映射是受springmvc管理的,所以修改mvc配置文件
1.2 注册功能实现
1、进行注册之前先进行数据的有效性验证。
a) 用户名不能重复
b) 确认密码和密码文本框的内容要一致。
c) 用户名、密码不能为空。
d) 手机不能为空 并且不能重复。
2、校验完成后注册。可以调用sso系统的注册接口完成注册。
注册jsp 页面
校验有两种,一是鼠标离开输入框以后ajax校验,还有是点击立即注册进行校验
<inputtype="text" id="regName" name="username" class="text />
<inputtype="button" id="registsubmit" value="立即注册" onclick="REGISTER.reg();"/>
点击调用注册函数
reg:function() {
if (this.inputcheck()) {
this.beforeSubmit();
}
}
inputcheck() 为true时 执行里面的方法,
inputcheck:function(){ 对文本框内容进行校验
//不能为空检查
if ($("#regName").val()==""){
alert("用户名不能为空");
$("#regName").focus(); // 获取光标
returnfalse;
}}
if ($("#pwd").val() != $("#pwdRepeat").val()){
alert("确认密码和密码不一致,请重新输入!");
$("#pwdRepeat").select();
$("#pwdRepeat").focus();
returnfalse;
}
beforeSubmit:function() {
//检查用户是否已经被占用
$.ajax({
url: REGISTER.param.surl +"/user/check/"+escape($("#regName").val())+"/1?r="+ Math.random(),
success: function(data){
if (data.data) {
//检查手机号是否存在
$.ajax({
url: REGISTER.param.surl +"/user/check/"+$("#phone").val()+"/2?r="+ Math.random(),
success: function(data){
if (data.data) {
REGISTER.doSubmit(); // 校验ok 调用注册函数
}else{
alert("此手机号已经被注册!");
$("#phone").select();
}
}
});
}else{
alert("此用户名已经被占用,请选择其他用户名");
$("#regName").select();
}
}
});
},
调用注册函数
doSubmit:function() {
$.post("/user/register",$("#personRegForm").serialize(),function(data){
if(data.status == 200){
alert('用户注册成功,请登录!');
REGISTER.login();
}else{
alert("注册失败!");
}
});
}
***************** 这套流程后续学习 *******************
2 登录功能的实现
2.1.1 打开登录页面
使用一个Controller跳转到登录页面。
login:function() {
location.href = "/user/showLogin";
returnfalse;
}
@RequestMapping("/showLogin")
public String showLogin() {
return"login";
}
jsp
<inputtype="button"class="btn-imgbtn-entry" id="loginsubmit"value="登录"/>
登录按钮没有绑定点击事件,搜搜 class 和 id
$(function(){
$("#loginsubmit").click(function(){
LOGIN.login();
});
})
调用login函数
login:function() {
if (this.checkInput()) {
this.doLogin();
}
}
调用校验的 函数
checkInput:function() {
if ($("#loginname").val()==""){
alert("用户名不能为空");
$("#loginname").focus();
returnfalse;
}
returntrue;
}
结果true 调用登录函数,
注意 $("#formlogin").serialize() 封装form参数传递给后台
doLogin:function() {
$.post("/user/login",$("#formlogin").serialize(),function(data){
if (data.status == 200) {
alert("登录成功!");
if (redirectUrl =="") {
location.href= "http://localhost:8082";
}else{
location.href= redirectUrl;
}
}else{
alert("登录失败,原因是:" + data.msg);
$("#loginname").select();
}
});
}
2.1.2 登录页面回调url
回调url应该是通过一个参数传递给显示登录页面的Controller。参数名为:redirect
需要把回调的url传递给jsp页面。当登录成功后,js的逻辑中判断是否有回调的rul,如果有就跳转到此url,如果没有就跳转到商城首页。
@RequestMapping("/showLogin")
public String showLogin(Stringredirect,Modelmodel){
model.addAttribute("redirect",redirect);
return"login";
}
jsp页面
var redirectUrl ="${redirect}";
获取值 然后判断是否有值有跳转没有值进入首页
if (redirectUrl == "") {
location.href= "http://localhost:8082";
}else{
location.href= redirectUrl;
}
3 使用拦截器实现用户登录
3.1 门户系统整合sso
在门户系统点击登录连接跳转到登录页面。登录成功后,跳转到门户系统的首页,在门户系统中需要从cookie中 把token取出来。所以必须在登录成功后把token写入cookie。并且cookie的值必须在系统之间能共享。
3.1.1 Cookie共享:
1、Domain:必须是相同的。
例如有多个域名:
Sso.taotao.com
Search.taotao.com
需要设置domain为:.taotao.com
2、设置path:/
1.1.2 工具类
如果是localhost不要设置domain。直接设置path就可以了。
1.1.3 在登录接口中添加写cookie的逻辑
// 写入到cookie
CookieUtils.setCookie(request,response, "TT_TOKEN",token);
//返回token
return TaotaoResult.ok(token);
JS文件里定义了,判断是否登录,取cookie 然后根据token 判断
var TT = TAOTAO = {
checkLogin: function(){
var _ticket = $.cookie("TT_TOKEN");
if(!_ticket){
return ;
}
$.ajax({
url: "http://localhost:8084/user/token/" + _ticket,
dataType: "jsonp",
type: "GET",
success: function(data){
if(data.status == 200){
var username =data.data.username;
var html = username +",欢迎来到淘淘!<a href=\"http://www.taotao.com/user/logout.html\"class=\"link-logout\">[退出]</a>";
$("#loginbar").html(html);
}
}
});
}
}
$(function(){
// 查看是否已经登录,如果已经登录查询登录信息
TT.checkLogin();
});
注意:
var _ticket = $.cookie("TT_TOKEN");
_ticket= _ticket.substring(1,_ticket.length-1);
if(!_ticket){
return ;
}
从cookie中取值 多了双引号“” , 截取字符串去掉前后双引号
3.1 模拟拦截url
需求:当访问商品详情页面时强制用户登录。(当有订单系统后就改为订单系统的url。)
3.1.1 创建拦截器
1、需要实现HandlerInterceptor接口。
2、实现拦截逻辑
3、需要在springmvc.xml中配置。
UserService 根据用户token 取用户信息
private String SSO_USER_TOKEN;
@Value("${SSO_PAGE_LOGIN}")
public String SSO_PAGE_LOGIN;
@Override
public TbUsergeTbUserByToken(String token) {
try {
// 调用sso系统的服务,根据token取用户信息
Stringjson= HttpClientUtil.doGet(SSO_BASE_URL + SSO_USER_TOKEN+ token);
//把json转换成TaotaoREsult
TaotaoResultresult= TaotaoResult.formatToPojo(json, TbUser.class);
if (result.getStatus() == 200) { // 取到值
TbUseruser= (TbUser)result.getData();
return user;
}
}catch(Exception e) {
e.printStackTrace();
}
return null;
}
拦截器实现
注意:
controller 里使用@value来获取属性不行
controller 是由子容器springmvc来扫描的
资源文件resource 是由spring来扫描的
子容器可以访问父容器的对象但是不可以访问属性
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private UserServiceImpl userService;
@Override
public booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// handler 执行之前处理
// 从cookie中取token
Stringtoken= CookieUtils.getCookieValue(request, "TT_TOKEN");
// 调用sso接口服务根据token取用户信息
TbUseruser= userService.geTbUserByToken(token);
//取不到用户信息
if (user == null) {
//跳转到登录页面,把用户请求的url作为参数传递给登录页面。
response.sendRedirect(userService.SSO_BASE_URL + userService.SSO_PAGE_LOGIN +
"?redirect="+ request.getRequestURL());
return false;
}
//取到用户信息,放行
//返回值决定handler是否执行。true:执行,false:不执行。
return true;
}
@Override
public voidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndViewmodelAndView)throwsException {
// handler 执行之后返回modelandview之前
}
springmvc 配置文件 配置
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截订单类请求 -->
<mvc:mapping path="/item/**"/>
<bean class="com.taotao.portal.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
4 购物车的实现
淘淘:购物车在用户不登陆的情况下也可以使用购物车。需要把购物车的商品信息写入cookie中。所有对购物车的操作都是操作cookie。有效 的降低数据库的压力。
缺点:换一台电脑后购物车的商品不能同步。
实现的工程:taotao-protal中实现购物车功能。只需要调用商品信息的服务,除此之外不需要和其他系统交互。
4.1 添加购物车商品
4.1.1 流程分析:
在商品详情页面点击“加入购物车”按钮提交一个请求吧商品id传递给Controller,Controller接收id,Controller调用Service根据商品id查询商品基本信息。
把商品写入cookie中,加入cookie之前先从cookie中把购物车的商品取出来判断当前购物车商品列表中是否有此商品,
如果有数量加一,如果没有添加一个商品,数量为1。展示给用户购物车列表。
4.1.2 Service层实现
功能:接收一个商品id,数量(默认为1),根据商品id查询商品信息。调用taotao-rest的服务。把商品添加到购物车,
先把购物车商品列表取出来,判断列表中是否有此商品,如果有就增加数量就可以了。
如果没有把此商品添加到商品列表。返回添加成功Taotaoresult。
因为cookie存储有限,根据页面需要创建一个pojo
创建购物车商品POJO:
public class CartItem {
private long id;
private String title;
private Integer num;
private long price;
private String image;
}
/**
* 添加商品到购物车
*/
@Override
public TaotaoResultaddCartItem(longitemId,intnum,
HttpServletRequestrequest,HttpServletResponse response){
CartItemcartItem= null;
//取购物车商品列表
List<CartItem>itemList= getItemList(request);
for (CartItem cItem : itemList) {
// 判断商品列表里有没有该商品
if (cItem.getId() == itemId) {
cItem.setNum(cItem.getNum() + num); // 存在修改数量
cartItem = cItem;
break;
}
}
// 商品列表里没有当前商品
if (null == cartItem) {
//根据商品id查询商品基本信息。
cartItem = new CartItem();
StringjsonString= HttpClientUtil.doGet(REST_BASE_URL + REST_BASE_ITEM+ itemId);
TaotaoResulttaotaoresult= TaotaoResult.formatToPojo(jsonString, TbItem.class);
if(taotaoresult.getStatus() ==200) {
TbItemtbItem= (TbItem)taotaoresult.getData();
cartItem.setId(tbItem.getId());
cartItem.setTitle(tbItem.getTitle());
cartItem.setImage(tbItem.getImage() == null ? "":tbItem.getImage().split(",")[0]);
cartItem.setNum(num);
cartItem.setPrice(tbItem.getPrice());
}
//添加到购物车列表
itemList.add(cartItem);
}
// 把购物车信息重新写到cookie中
CookieUtils.setCookie(request, response, "TT_CART",JsonUtils.objectToJson(itemList));
return TaotaoResult.ok();
}
/** 从cookie中取商品列表 */
private List<CartItem>getItemList(HttpServletRequest request){
//从cookie中取商品列表
// 这个cookie 要编码不然信息直白的写在cookie里不太好
StringjsonValue= CookieUtils.getCookieValue(request, "TT_CART",true);
if (null == jsonValue) {
return new ArrayList<>();
}
try {
List<CartItem>list= (List<CartItem>) JsonUtils.jsonToList(jsonValue, CartItem.class);
return list;
}catch(Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
添加到购物车controller
@RequestMapping("/add/{itemId}")
public String addCartItem(@PathVariable long itemId,
@RequestParam(defaultValue="1") Integer num,
HttpServletRequestrequest,HttpServletResponse response){
TaotaoResultresult= catItemService.addCartItem(itemId, num, request, response);
return "cartSuccess";
}