zoukankan      html  css  js  c++  java
  • SSM商城项目(十一)

    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.comsso.e3.comorder.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语句。

  • 相关阅读:
    stm32 单片机
    #pragma hdrstop
    #pragma预处理命令
    用define 宏定义注释符号
    ANSI 标准C 还定义了如下几个宏
    国际C 语言乱码大赛(IOCCC )
    深入浅出C语言中的柔性数组
    有符号数与无符号数之间运算问题
    c 语言 register 关键字
    Windows堆思维导图--Windows pro sp3
  • 原文地址:https://www.cnblogs.com/huozhonghun/p/10135240.html
Copyright © 2011-2022 走看看