1. 程式人生 > >學習淘淘商城第一百零三課(利用攔截器實現登入功能及訂單確認頁面展示)

學習淘淘商城第一百零三課(利用攔截器實現登入功能及訂單確認頁面展示)

        我們上節課一起搭建了訂單的服務工程和web工程,我們參考京東可以知道,京東在沒有登入時就可以使用購物車,但是當要真正付款的時候,一定是要求登入的。也就是說由購物車列表頁面直接跳轉到登入頁面去登入。這顯然用到了攔截器的功能,這節課我們便一起實現登入功能。

         下圖便是購物車列表頁面,我們點選"去結算",如果當前使用者還沒登入,是必須要先登入的。


        下面我們便來寫攔截器,攔截器是要實現HandlerInterceptor的,我們在taotao-order-web工程的src/main/java目錄下新建一個包com.taotao.order.interceptor並在該包下新建LoginInterceptor攔截器(實現HandlerInterceptor),如下圖所示。


           LoginInterceptor所有程式碼如下:

package com.taotao.order.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.sso.service.UserService;

public class LoginInterceptor implements HandlerInterceptor {
	
	@Value("${TOKEN_KEY}")
	private String TOKEN_KEY;
	@Value("${SSO_URL}")
	private String SSO_URL;
	@Autowired
	private UserService userService;


	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 執行的時機,在handler之前先執行此方法,攔截請求讓使用者登入就在這個方法攔截
		//1.從cookie中取token資訊
		String token = CookieUtils.getCookieValue(request, TOKEN_KEY);
		//2.如果取不到token,跳轉到sso的登入頁面,需要把當前請求的url做為引數傳遞給sso,sso登入成功之後跳轉回請求的頁面
		if(StringUtils.isBlank(token)){
			//取當前請求的url
			String requestURL = request.getRequestURL().toString();
			//跳轉到登入頁面,用redirect比較合適,登入之後還要回到當前頁面,因此要在請求url中新增一個回撥地址
			response.sendRedirect(SSO_URL+"/page/login?url="+requestURL);
			//既然沒登入,肯定是要攔截的
			return false;
		}
		//3.取到token,呼叫sso系統的服務判斷使用者是否登入,既然要呼叫SSO服務介面,就要依賴這個taotao-sso-interface
		TaotaoResult result = userService.getUserByToken(token);
		//4.如果使用者未登入(有token,但是已經過期,也算是沒登入),即沒有取到使用者資訊。跳轉到sso的登入頁面
		//返回的TaotaoResult如果沒有登入的話,狀態碼是400,如果登入了的話,狀態碼是200
		if(result.getStatus() != 200){
			//取當前請求的url
			String requestURL = request.getRequestURL().toString();
			//跳轉到登入頁面,用redirect比較合適,登入之後還要回到當前頁面,因此要在請求url中新增一個回撥地址
			response.sendRedirect(SSO_URL+"/page/login?url="+requestURL);
			//既然沒登入,肯定是要攔截的
			return false;
		}
		//5.如果取到使用者資訊,就放行。
		//返回值true表示放行,返回false表示攔截
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// handler執行之後,modelAndView返回之前,可以對返回值進行處理

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// 在ModelAndView返回之後,這時只能做些異常處理了

	}

}
         可以看到,我們在程式碼中用到了兩個常量,常量我們要定義在配置檔案當中,如下圖所示


        配置檔案中內容如下:

#token在cookie中儲存的key,這個key與我們SSO工程定義的key值是一樣的
TOKEN_KEY=TT_TOKEN
#SSO系統的url
SSO_URL=http://localhost:8088
        preHandle方法的第3步通過token取使用者資訊,顯然用到了SSO服務的介面,因此我們需要在taotao-order-web工程依賴taotao-sso-interface工程,如下圖所示。


         依賴程式碼如下:

<dependency>  
        <groupId>com.taotao</groupId>  
        <artifactId>taotao-sso-interface</artifactId>  
        <version>0.0.1-SNAPSHOT</version>  
    </dependency>
         光依賴taotao-sso-interface還不行,我們還得在springmvc.xml檔案中引用taotao-sso-service釋出的dubbo服務,另外我們寫的攔截器Spring是不知道的,我們得告訴Spring我們寫了這個攔截器,於是需要在springmvc.xml檔案中配置下攔截器。如下圖所示。


          修改完後springmvc.xml檔案的內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
       
    <!-- 載入配置檔案 -->
    <context:property-placeholder location="classpath:resource/resource.properties"/>    
	<!-- 配置註解驅動 -->
	<mvc:annotation-driven />
	<!-- 檢視解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- 配置包掃描器,掃描@Controller註解的類 -->
	<context:component-scan base-package="com.taotao.order.controller"/>
	<!-- 配置攔截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/order/**"/>
			<bean class="com.taotao.order.interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>
	
	<!-- 引用dubbo服務 -->
	<dubbo:application name="taotao-order-web"/>
	<dubbo:registry protocol="zookeeper" address="192.168.156.14:2181"/>
	<dubbo:reference interface="com.taotao.sso.service.UserService" id="userService" />
</beans>
         我們是要由購物車列表頁面訪問訂單頁面時觸發攔截器的,因此我們要先處理購物車列表頁面,如下圖所示,我給大家提供的靜態頁面這裡已經改過了,不用修改。

 

        由於要訪問訂單頁面,因此我們需要把訂單的靜態資源放到taotao-order-web工程下,大家可以到http://download.csdn.net/detail/u012453843/9872711這個地址下載相關靜態資原始檔。將css、images、js檔案放到webapp目錄下,把jsp放到WEB-INF目錄下。


          我們要訪問的訂單頁面是order-cart.jsp頁面,如下圖所示,這個頁面中"cartList"是Controller返回的購物車列表,cart的屬性一定要正確,我給大家的靜態資原始檔已經修改好了,可以直接使用。


         我們需要在taotao-order-web寫一個Controller來響應購物車列表請求訪問訂單頁面的請求,如下圖所示。


         OrderController程式碼如下:

package com.taotao.order.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSON;
import com.taotao.common.utils.CookieUtils;
import com.taotao.pojo.TbItem;

@Controller
public class OrderController {
	@Value("${CART_KEY}")
    private String CART_KEY;
	
	@RequestMapping("/order/order-cart")
	public String showOrderCart(HttpServletRequest request){
		//使用者必須是登入狀態
		//取使用者ID
		//根據使用者ID取收穫地址列表,這裡就使用靜態資料了
		//把收貨地址列表取出傳遞給頁面
		//從cookie中取購物車商品列表展示到頁面
		List<TbItem> cartList = getCartItemList(request);
		request.setAttribute("cartList", cartList);
		//返回邏輯檢視
		return "order-cart";
	}
	
	private List<TbItem> getCartItemList(HttpServletRequest request){
		//從cookie中取購物車商品列表
		String json = CookieUtils.getCookieValue(request, CART_KEY, true);//為了防止亂碼,統一下編碼格式
		if(StringUtils.isBlank(json)){
			//說明cookie中沒有商品列表,那麼就返回一個空的列表
			return new ArrayList<TbItem>();
		}
		List<TbItem> list = JSON.parseArray(json, TbItem.class);
		return list;
	}
}
          上面程式碼中用到了常量CART_KEY,因此我們需要在配置檔案中配置下這個常量,如下圖所示。

         當前配置檔案的內容如下:

#token在cookie中儲存的key,這個key與我們SSO工程定義的key值是一樣的
TOKEN_KEY=TT_TOKEN
#SSO系統的url
SSO_URL=http://localhost:8088
#購物車在cookie中儲存的Key
CART_KEY=TT_CART

         下面我們先來測試下攔截器是否好使,我們要啟動taotao-order-web工程,但是要先將taotao-order聚合工程打包到本地maven倉庫,方法是在taotao-order工程上右鍵----->Run As------>Maven install,如下圖所示。


         我們啟動taotao-order-web工程,在taotao-order-web工程上右鍵------>Run As----->Maven build,如下圖所示。


         在彈出的對話方塊中的Goals一欄輸入"clean tomcat7:run",如下圖所示。然後點選"Apply",最後點選"Run"。


         啟動成功後,我們再點選本篇部落格第一張圖的"去結算",就可以看到,頁面跳轉到了登入頁面,如下圖所示。說明我們的攔截器沒問題。


           我們輸入使用者名稱和密碼進行登入,發現登入到淘淘商城首頁了,這不是我們想要去的頁面,應該到訂單確認頁面頁面才對。


          登入有沒有成功在login.jsp當中有判斷,如下圖所示,可以看到,js首先會去嘗試獲取從Controller端傳過來的回撥地址,如果取到了回撥地址,那麼登入成功後會跳轉到回撥地址,如果沒有取到回撥地址,那麼登入成功後直接訪問的便是淘淘商城首頁,在上圖中之所以我登入成功後訪問到的是淘淘商城首頁就是因為我們沒有在PageController 當中添加回調地址。


          下面我們到taotao-sso-web工程的PageController中簡單做下修改,如下圖所示,我們在showLogin方法中添加了兩個引數,一個是回撥地址url,另一個是用來給jsp頁面新增屬性的Model,回撥地址url也不是憑空來的,它是由攔截器重定向時就指定好的。


          修改後的PageController程式碼如下:

package com.taotao.sso.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 展示登入和註冊頁面的Controller
 * @author 志鵬
 *
 */
@Controller
public class PageController {
   
	@RequestMapping("/page/register")
	public String showRegister(){
		return "register";
	}
	
	@RequestMapping("/page/login")
	public String showLogin(String url,Model model){
		model.addAttribute("redirect", url);
		return "login";
	}
}
          既然我們修改了taotao--sso-web工程,下面我們便重啟taotao-sso-web工程,重啟後,我們重新來測試一下,如果你是剛登入的話,cookie中已經有你的登入資訊而且token還沒過期,要想達到使用者未登入的情況,有兩種方法,一是刪除cookie中的TT_TOKEN,如下圖所示,另一種方法就是等,等30分鐘,30分鐘後token過期。顯然,我們刪除cookie中的TT_TOKEN比較靠譜。


        刪除了cookie中的token或token過期後,我們還是從購物車列表頁面(本篇部落格第一張圖)點選"去結算",還是會讓我們登入,登入後會提示登入成功,點選"確定"後,我們看到的是下圖所示頁面,而不再是淘淘商城首頁了。下圖便是訂單確認頁面。

        但是當前這個頁面頭部還是顯示的是未登入狀態,我們參考單點登入系統的程式碼,在taotao-order-web工程的js目錄下找到base-v1.js,開啟它修改最上面的兩個方法。


         修改的程式碼如下,這樣從訂單確認頁面便可以點選"登入"或"註冊"跳轉到相應的頁面。

function login() {
    return location.href = "http://localhost:8088/page/login";
}
function regist() {
    return location.href = "http://localhost:8088/page/register";
}
         我們再修改下js目錄下的taotao.js檔案,其實這個檔案我們只需要將埠修改為8088就可以了。

        下面我們重啟taotao-order-web工程,重啟後,我們重新整理訂單確認頁面,便可以看到頭部有使用者資訊了。



相關推薦

學習商城第一利用攔截實現登入功能訂單確認頁面展示

        我們上節課一起搭建了訂單的服務工程和web工程,我們參考京東可以知道,京東在沒有登入時就可以使用購物車,但是當要真正付款的時候,一定是要求登入的。也就是說由購物車列表頁面直接跳轉到登入頁面去登入。這顯然用到了攔截器的功能,這節課我們便一起實現登入功能。  

【leetcode 簡單】 第一題 最小移動次數使數組元素相等

lee strong leet 一個 輸出 需要 相等 輸入 def 給定一個長度為 n 的非空整數數組,找到讓數組所有元素相等的最小移動次數。每次移動可以使 n - 1 個元素增加 1。 示例: 輸入: [1,2,3] 輸出: 3 解釋: 只需要3次移動(註意每次移

leecode第一四題二叉樹的最大深度

public int http code dep def com node src /** * Definition for a binary tree node. * struct TreeNode { * int val; * T

前端之路——jQuery第利用已學的jq,製作一個失去焦點時,為空報錯的表單驗證

又來了,穩穩的來到了jQuery的第三課。。。今天任務比較難啊,自己需要寫個失去焦點時,為空報錯的表單驗證。 其實簡單想想,很好做 我們經常在那些輸入賬號密碼的介面就有這判斷驗證,好的,收拾心情,開始學習!!! 今天覆習的內容: 1:函式寫法 2:顯示與隱藏 3:焦點事件

python學習第一八天:MongoDB,pymongo

MongoDB: 資料庫,nosql [{ id:1 name:"蔡文姬" age: 16 gender:"女" }, { id:1 name:"蔡文姬" age: 16 sex:["女","girl","老阿姨"

學習商城第九十六購物車實現分析工程搭建

        關於購物車模組,京東和淘寶並不一樣,京東允許使用者在沒有登入的情況下就使用購物車,而且加到購物車裡面的商品可以一直儲存著(其實是放到了Cookie當中,如果清空了Cookie也就清空購物車了)。而淘寶則是必須先登入才能將商品新增到購物車當中,就使用者體驗來說

學習商城第八十九單點登入之通過token獲取使用者資訊

        首先還是看介面文件關於通過token獲取使用者資訊的說明,如下圖所示。             看了說明文件我們便知道該怎麼做了,在taotao-sso-interface工程的UserService介面類中新增一個介面,如下圖所示。          

學習商城第九十七商品詳情頁面對加入購物車進行改造

        我們訪問淘淘商城首頁(前提是啟動了所有的服務及工程,雖然有個別工程用不上,不過也沒關係),在搜尋框中輸入要搜尋的商品,我以前新增過"金立M2017"這款手機,我就搜尋它。          搜尋到的結果頁面如下圖所示。           我們再點選這款

學習商城第六十六商品詳情快取的實現

       上節課我們一起分析了下商品詳情快取策略,這節課我們一起實現商品詳情快取的新增。        首先,我們要想清楚快取應該加到哪個工程當中,現在我們有兩個工程可以選擇,第一個工程是taotao-item-web(商品詳情工程),如果把快取加到這個工程的話,由於該

學習商城第四十四首頁跳轉到搜尋頁面搜尋實現分析

       上節課我們一起學習了將資料從資料庫匯入到索引庫,這節課我們一起學習下首頁跳轉到搜尋頁面。        我們要訪問taotao-portal-web工程就要先啟動redis服務(大家根據自己使用的情況啟動,使用的是單機版就啟動單機版伺服器,使用的是叢集就啟動叢

學習商城第五十四為何引入ActiveMQ

        我們在學習Solr索引的時候,每當新增一個商品後,都要把資料庫中的資料全部重新匯入到索引庫,特別消耗效能和時間,這顯然是我們所不能忍受的,這就需要優化我們的方案。最好是在商品新增的時候就單獨將該商品同步到索引庫,這樣便簡單快捷地實現了資料庫與索引庫的同步。

學習商城第八十六單點登入使用者註冊Controller層實現測試

        上節課我們一起學習了使用者註冊Service層的實現,這節課我們實現Controller層並且測試介面是否好用。         在taotao-sso-web工程的UserController類新增如下圖所示標註的程式碼。           新增的程式

python第一五天 ---Django 基礎

moni lec primary test sage install 允許 os.path com 一 路由系統 URL 1 url(r‘^index/‘,views.index) url(r‘^home/‘, views.Home.as_view(

python第一九天---Django 4

超時 display form 完成 save blog username back use session :1. Session 基於Cookie做用戶驗證時:敏感信息不適合放在cookie中 a. Session原理 Cookie是保存在用戶瀏覽

fast.ai 深度學習筆記:第一部分第

原文:Deep Learning 2: Part 1 Lesson 3 作者:Hiromi Suenaga 課程論壇 學生建立的有用材料: AWS 操作方法 TMUX 第 2 課總結 學習率查詢器 PyTorch

移除連結串列元素leetcode簡單篇二

刪除連結串列中等於給定值 val 的所有節點。 示例: 輸入: 1->2->6->3->4->5->6, val = 6 輸出: 1->2->3->4->5 struct ListNode* remove

“全棧2019”Java第一二章:哪些作用域可以宣告區域性內部類?

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第一百零二章:哪些作用域可以宣告區域性內部類?

“全棧2019”Java第一一章:區域性內部類覆蓋作用域內成員詳解

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第一百零一章:區域性內部類覆蓋作用域內成員詳解

“全棧2019”Java第一四章:匿名內部類與外部成員互訪詳解

內部 原創 時間 鏈接 內部類 版權 外部 工程 公眾 難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文鏈接 “全棧2019”Java第一百零四章:匿名內部類與外部成員互

“全棧2019”Java第一五章:匿名內部類覆蓋作用域成員詳解

作用域 分享 inf tel src 工程師 alt 計劃 抽象類 難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文鏈接 “全棧2019”Java第一百零五章:匿名內部類