SSO单点登录redis配置

1  Redis集群的方式

1.1  切换redis的配置方式

1.  就用6379一个redis

Spring配置文件中 添加<bean id=”jedis”class=”Jedis.class”></bean>

@Autowired

Private Jedis jedis;

2.  采用redis的分片

a)  分别使用3台redis提供服务,.配置文件参见笔记.

1.2  其他的环境问题

Tomcat:tomcat插件

Mysql:window中的Mysql

Nginx: 检查配置文件  拷贝别人的conf

2  单点登录

2.1  SSO复习

2.1.1    单点中的要素

1.  Ticket:它是一个加密后的密码(MD5),用户登录后的凭证

2.  用户信息:根据用户名和密码查询到的真实的用户信息  UserJSON

3.  如何取值

2.1.2    HttpCLient的请求方式

说明:Java操作HTTP请求的API,所以httpClient发出请求时,浏览器监听不到

2.1.3    HttpClient传参方式

3  用户登陆实现

3.1  SSO单点登录实现

3.1.1    前台Controller

//用户登陆 http://www.jt.com/service/user/doLogin?r=0.582247581950398

   //通过login.jsp检测登陆的username和password是否正确

   @RequestMapping("/doLogin")

   @ResponseBody

   public SysResult doLogin(String username,String password,

         HttpServletRequest request,HttpServletResponseresponse){

      //判断用户名和密码是否为null

      if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){

         return SysResult.build(201, "用户名密码不能为空");

      }

      //当前输入的用户名是正确的

      try {

         //获取用户的ticket

         String ticket =

                userService.findUserByUP(username,password);

         //ticket不为空

         if(!StringUtils.isEmpty(ticket)){

            //如果ticket数据不为空 则写入cookie

            //Cookie[] cookies =request.getCookies();

            //Cookie的名称必须为 JT_TICKET

         CookieUtils.setCookie(request, response, "JT_TICKET", ticket);

            return SysResult.oK(ticket);

         }

      } catch (Exception e) {

         e.printStackTrace();

      }

      return SysResult.build(201, "用户登陆失败");

   }

3.1.2    编辑前台Service

//返回ticket数据

   @Override

   public String findUserByUP(String username, String password) {

      String uri = "http://sso.jt.com/user/login";

      Map<String, String> map = new HashMap<String,String>();

      //注意不要有空格  为了网络中传递的速度更快 采用简单字符传递

      map.put("u", username);

      map.put("p", password);

      try {

         String resutJSON = httpClient.doPost(uri,map);

         //判断数据是否有效  将其转化为Sysresult对象

         //为了防止data数据为null时,返回的字符串为"null"对代码产生影响

         SysResult sysResult =

         objectMapper.readValue(resutJSON,SysResult.class);        //判断SSO返回是否正确

         if(sysResult.getStatus() == 200){

            return (String) sysResult.getData();

        

      } catch (Exception e) {

         e.printStackTrace();

      }

      returnnull;

   }

3.1.3    编辑单点Controller

/**

    * @RequestParam作用:

    * 表示参数接收时采用 u的关键字获取.将获取到的value值交给

    *  username属性

    * @paramusername

    * @parampassword

    * @return

    */

   //http://sso.jt.com/user/login

   @RequestMapping("/login")

   @ResponseBody  //形成的JSON数据 {status=201,msg="",data="null"}

   public SysResult doLogin(@RequestParam("u")String username,

         @RequestParam("p")String password){

      try {

         //获取ticket信息

         String ticket = userService.findUserByUP(username,password);

         return SysResult.oK(ticket);

      } catch (Exception e) {

         e.printStackTrace();

      }

     

      return SysResult.build(201, "登录失败");

   }

3.1.4    编辑单点Service

/**

    * 1.验证用户名和密码是否正确

    * 2.需要将用户的明文加密为密文

    * 3.如果用户信息校验通过.准备redis缓存数据

    * 4.生成ticket= md5(“JT_TICKET_” + System.currentTime + username

    * 5.将User对象转化为JSON数据

    * 6.将ticket和UserJSON数据存入redis

    * 7.return 返回ticket

    */

   @Override

   public String findUserByUP(String username, String password) {

     

      //根据用户名和加密后的密码查询用户信息

      String md5Password = DigestUtils.md5Hex(password);

      User user = userMapper.selectUserByUP(username,md5Password);

     

      //判断user是否为null

      if(user !=null){

        

         //准备ticket信息

         String ticket = "JT_TICKET_" + System.currentTimeMillis()

         + user.getUsername();

         //加密ticket

         String md5Ticket = DigestUtils.md5Hex(ticket);

        

         try {

            String userJSON = objectMapper.writeValueAsString(user);

            //将数据存入redis

            jedisCluster.set(md5Ticket, userJSON);

            returnmd5Ticket;

           

         } catch (Exception e) {

            e.printStackTrace();

         }

      }

      returnnull;

   }

3.2  登录数据的回显

3.2.1    分析页面JS

说明:用户发出JSONP请求 实现用户信息回显

Js文件在jt.js中第一行.

说明:

    该JS通过Cookie获取JT_TICKET信息.如果TICKET不为null.则会发送AJAX请求.请求USERJSON数据.用于页面展现.

如果ticket为null,则说明用户没有登陆,则不予显示.

3.2.2    用户信息的回显

//根据ticket查询用户的JSON信息

   //http://sso.jt.com/user/query/" +_ticket  JSNP的提交

   @RequestMapping("/query/{ticket}")

   @ResponseBody

   public Object findUserByTicket(@PathVariable String ticket,

         String callback){

      //获取用户的JSON数据

      String userJSON = jedisCluster.get(ticket);

     

      MappingJacksonValue jacksonValue =

            new MappingJacksonValue(SysResult.oK(userJSON));

      //设定返回的方法名称

      jacksonValue.setJsonpFunction(callback);

     

      returnjacksonValue;

     

   }

3.2.3    用户的登出

思路:

    1.cookie中获取ticket信息

    2.删除redis缓存

    3.删除cookie信息

    4.跳转页面到系统欢迎页面

  实现:

   //用户的登出操作  //user/logout.html

   //1.cookie中获取ticket信息

   //2.删除redis缓存

   //3.删除cookie信息

   //4.跳转页面到系统欢迎页面

   @RequestMapping("/logout")

   public String logout(HttpServletRequest request,HttpServletResponseresponse){

     

      String ticket = CookieUtils.getCookieValue(request,"JT_TICKET");

      jedisCluster.del(ticket);

      CookieUtils.deleteCookie(request, response, "JT_TICKET");

     

      //通过重定向的方式返回系统首页 

      return"redirect:/index.html";

   }

4  京淘购物车实现

4.1  购物车系统

4.1.1    前台如何连接购物车

4.2  购物车创建

4.2.1    新建购物车项目

选择web骨架

定义项目名称 jt-cart

4.2.2    引入jar包和引入工具类

引入parent项目

依赖工具类文件

4.2.3    添加tomcat插件

<!--修改端口号8094  -->

  <build>

      <plugins>

         <plugin>

            <groupId>org.apache.tomcat.maven</groupId>

            <artifactId>tomcat7-maven-plugin</artifactId>

            <version>2.2</version>

            <configuration>

                <port>8094</port>

                <path>/</path>

            </configuration>

         </plugin>

      </plugins>

   </build>

4.2.4    修改配置文件

1.  SpringMVC的配置文件

2.  修改Spring的配置文件

3.  修改Spring-mycatis的配置文件

 

4.2.5    根据表设计创建tb-cart表

说明:通过PD打开表设计.通过Sql语句创建jt_cart表

1.将sql语句复制到MYsql数据库中执行即可

    建表完成后添加2条测试数据即可.

 

   

4.2.6    构建POJO对象

@Table(name="tb_cart")

publicclass Cart extendsBasePojo{

   @Id

   @GeneratedValue(strategy=GenerationType.IDENTITY)

   private Long id;   //购物车主键信息

   private Long userId//用户的id

   private Long itemId//商品的Id

   private String itemTitle;   //商品标题

   private String itemImage;   //商品的首图

   private Long    itemPrice//商品的价格

   private Integer num;     //商品数量

4.2.7    构建Mapper对象

public interface CartMapper extends SysMapper<Cart>{

}

4.2.8    构建Service

@Service

publicclass CartServiceImpl implementsCartService {

  

   @Autowired

   private CartMapper cartMapper;

}

4.2.9    构建Controller

@Controller

publicclass CartController {

  

   @Autowired

   private CartService cartService;

}

4.2.10  修改nginx

#京淘购物车系统

   server {

      listen80;

      server_namecart.jt.com;

      location/ {

         proxy_passhttp://127.0.0.1:8094;

      }

   }

修改nginx之后重启nginx

3.  修改HOST文件

# 京淘电商环境

127.0.0.1      image.jt.com

127.0.0.1      manage.jt.com

127.0.0.1      www.jt.com

127.0.0.1      sso.jt.com

127.0.0.1      cart.jt.com

127.0.0.1      order.jt.com

5  购物车实现

5.1  根据userId查询信息

5.1.1    接口文档定义

请求方法

GET

URL

http://cart.jt.com/cart/query/{userId}

参数

userId 用户ID

示例

http://cart.jt.com/cart/query/1

返回值

{

status: 200  //200 成功,201 没有查到

msg: “OK”  //返回信息消息

data:

[1]

0:

{

created: 1418092628000

updated: 1418092628000

id:1

userId:1

itemId:39

itemTitle: “java核心技术

itemImage: http://image.jt.com/images/2015/06/11/20150309118.jpg

itemPrice: 87200

num:1

}

}

 

 

 

5.1.2    购物车Controller

/**

    * 任务:根据用户id查询购物车信息

    * url:http://cart.jt.com/cart/query/{userId}

    * 返回SysResult对象 并且data数据中保存cartList的JSON数据

    */

   @RequestMapping("/query/{userId}")

   @ResponseBody

   public SysResult findCartByUserId(@PathVariable Long userId){

      try {

         //获取cartList数据

         List<Cart> cartList =

                cartService.findCartByUserId(userId);

         String cartListJSON =

                objcetMapper.writeValueAsString(cartList);

         return SysResult.oK(cartListJSON);

      } catch (Exception e) {

         e.printStackTrace();

         return SysResult.build(201, "查询失败");

     

   }

5.1.3    编辑Service

@Override

   public List<Cart> findCartByUserId(Long userId) {

     

      Cart cart = new Cart();

      cart.setUserId(userId);

      //通过通用Mapper查询购物车信息

      returncartMapper.select(cart);

   }

5.1.4    模拟访问

说明:模拟正确的请求,查看代码编辑是否正确.

       

5.1.5    前台访问分析

说明:根据页面请求响应页面

分析页面元素:

页面中需要循环遍历CartList集合.从Reqest域中获取

        

5.1.6    前台Controller编辑

@Controller

@RequestMapping("/cart")

publicclass CartController {

  

   @Autowired

   private CartService cartService;

  

  

   //转向到购物车页面   /cart/show.html

   @RequestMapping("/show")

   public String findCartByUserId(Model model){

     

      Long userId = 7L;  //暂时写死UserId后期维护

     

      //查询购物车列表信息

      List<Cart> cartList =

            cartService.findCartByUserId(userId);

     

      //将数据写入request域中

      model.addAttribute("cartList", cartList);

      //转向cart.jsp页面

      return"cart";

   }

5.1.7    编辑前台Service

@Service

publicclass CartServiceImpl implementsCartService {

  

   @Autowired

   private HttpClientService httpClient;

  

   privatestatic ObjectMapper objectMapper = new ObjectMapper();

  

  

   @Override

   public List<Cart> findCartByUserId(Long userId) {

      String uri = "http://cart.jt.com/cart/query/" + userId;

     

      try {

         String resultJSON = httpClient.doGet(uri);

         //数据data的数据类型是Object ,需要转化为LIst集合,

         //但是转化会失败

         //objectMapper.readValue(resultJSON,SysResult.class);

        

         //通过ObjectMapper 直接获取json的属性

         //要求:JSON串必须是对象的JSON{id:1,name:tom}

         //而不能是List/arrayJSON [value1,value2]

        

         //{id:1,name:tom}

         JsonNode jsonNode = objectMapper.readTree(resultJSON);

         //JSON数据转化为String类型的字符串 [{},{},{}]

         String cartListJSON = jsonNode.get("data").asText();

        

         //cartListJSON数转化为List集合

         Cart[] carts =

      objectMapper.readValue(cartListJSON,Cart[].class);

        

         List<Cart> cartList = Arrays.asList(carts);

        

         returncartList;

        

      } catch (Exception e) {

         e.printStackTrace();

      }

      returnnull;

   }

5.2  购物车数量修改

5.2.1    业务接口文档定义

请求方法

GET

URL

http://cart.jt.com/cart/update/num/{userId}/{itemId}/{num}

参数

userId 用户名ID

itemId 商品ID

num 数量

示例

http://cart.jt.com/cart/upadate/num/001/002/2

返回值

{

status: 200

msg: “OK”

data:null

}

 

 

5.2.2    编辑修改Controller

//http://cart.jt.com/cart/update/num/{userId}/{itemId}/{num}

   @RequestMapping("/update/num/{userId}/{itemId}/{num}")

   @ResponseBody

   public SysResult updateCartNum(

         @PathVariable Long userId,

         @PathVariable Long itemId,

         @PathVariable Integer num){

      try {

         Cart cart = new Cart();

         cart.setUserId(userId);

         cart.setItemId(itemId);

         cart.setNum(num);

         cartService.updateCartNum(cart);

         return SysResult.oK();

        

      } catch (Exception e) {

         e.printStackTrace();

         return SysResult.build(201,"修改数量失败");

      }

5.2.3    编辑购物车Service

@Override

   publicvoid updateCartNum(Cart cart) {

      //添加修改时间

      cart.setUpdated(newDate());

      cartMapper.updateNum(cart);

  

5.2.4    编辑映射文件

<mapper namespace="com.jt.cart.mapper.CartMapper">

  

   <!--根据userIditemId修改购物车的数量  -->

  

   <update id="updateNum">

      update tb_cart set num = #{num} where

      user_id = #{userId} and item_id = #{itemId}

   </update>

  

  

</mapper>

     

5.2.5    代码模拟测试

说明:根据业务中的路径测试方法编辑是否正确

5.2.6    分析页面

url:http://www.jt.com/service/cart/update/num/1474391958/101

 

说明:

   数量的修改不需要校验,Controller返回任意值即可.

5.2.7    编辑前台Controller

//修改购物车商品数量

   //urlhttp://www.jt.com/service/cart/update/num/1474391958/101

   @RequestMapping("/update/num/{itemId}/{num}")

   @ResponseBody

   public String updateCartNum(@PathVariableLong itemId,

         @PathVariable Integer num){

      Long userId = 7L;  //获取userId

      Cart cart = new Cart();//为属性赋值

      cart.setUserId(userId);

      cart.setItemId(itemId);

      cart.setNum(num);

      cartService.updateCartNum(cart);

     

      return"";

   }

5.2.8    编辑前台Service

@Override

   publicvoid updateCartNum(Cart cart) {

      //定义urihttp://cart.jt.com/cart/update/num/{userId}/{itemId}/{num}

      String uri =

            "http://cart.jt.com/cart/update/num/"+cart.getUserId()+

            "/"+cart.getItemId()+"/"+cart.getNum();

      try {

         httpClient.doGet(uri);

      } catch (Exception e) {

         e.printStackTrace();

      }

   }

5.2.9    效果展现

说明:当数量增减时,价格也会跟着变化,表示测试成功

5.3  商品的删除

5.3.1    接口文档定义

请求方法

GET

URL

http://cart.jt.com/cart/delete/{userId}/{itemId}

参数

userId 用户ID

itemId 商品ID

示例

http://cart.jt.com/cart/delete/2/6

返回值

{

status: 200

msg: “OK”

data:null

}

 

 

5.3.2    编辑购物车Controller

/**

    * 编辑商品的删除

    *url:http://cart.jt.com/cart/delete/{userId}/{itemId}

    */

   @RequestMapping("/delete/{userId}/{itemId}")

   @ResponseBody

   public SysResult deleteCart(@PathVariableLong userId,

         @PathVariable Long itemId){

      try {

         cartService.deleteCart(userId,itemId);

         return SysResult.oK();

      } catch (Exception e) {

         e.printStackTrace();

         return SysResult.build(201,"删除购物车失败");

     

   }

5.3.3    定义购物车Service

@Override

   publicvoid deleteCart(Long userId, Long itemId) {

      Cart cart = new Cart();

      cart.setUserId(userId);

      cart.setItemId(itemId);

     

      //调用父类的方法规范:调用父类的方法时最好添加super

      super.deleteByWhere(cart);

  

5.3.4    模拟删除操作

5.3.5    前台的删除

说明:当前台数据删除时,应该再次跳转到购物车列表页面.

5.3.6    编辑前台Controller

//删除购物车   /cart/delete/7.html

   @RequestMapping("/delete/{itemId}")

   public String deleteCart(@PathVariableLong itemId){

     

      Long userId = 7L;

      cartService.deleteCart(userId,itemId);

      //跳转到购物车列表页面  满足springMVC的要求 *.html

      return"redirect:/cart/show.html";

   }

5.3.7    编辑前台Service

@Override

   publicvoid deleteCart(Long userId, Long itemId) {

      //定义uri  进行路径拼接

      String uri = "http://cart.jt.com/cart/delete/"+userId+"/"+itemId;

      try {

         httpClient.doGet(uri);

      } catch (Exception e) {

         e.printStackTrace();

     

   }

6  作业:

1.  实现购物车新增的功能

功能描述:

通过查询商品详细页展现商品信息.当点击加入购物车时实现该业务逻辑

 根据接口文档的规范完成.

猜你喜欢

转载自blog.csdn.net/qq_40680190/article/details/79764894