1. 程式人生 > >【J2EE】模仿天貓商城(前臺篇)-01

【J2EE】模仿天貓商城(前臺篇)-01

完成了j2ee商城後臺的開發,就到前臺了,前臺的功能總體來說比後臺要多,而且也是包含許多比較常用的業務。將業務分為需要登入才能進行的業務和無需登入也能進行的業務。

無需登入:註冊,登入,退出,產品頁,模態登入,搜尋

需要登入:購買,新增購物車,結算,檢視購物車,生產訂單,檢視訂單,評價等

前臺主頁由五個jsp構成

1.header.jsp引入了標準標籤庫,js,css,自定義javascript函式等

2.top.jsp

 3.search.jsp

4.homePage.jsp,就是中間最大那塊。。。在它下面又分了幾個小塊

      4.1categoryAndcarousel.jsp 分類和輪播

      4.2categoryMenu.jsp豎狀分類選單

      4.3productsAsideCategorys.jsp豎狀分類選單右側的推薦產品列表

      4.4carousel.jsp輪播

      4.5homepageCategoryProducts.jsp主題的17種分類以及每種分類對應的5個產品

5. footer.jsp頁尾部分,除了顯示頁尾的靜態資訊外,還包含了modal.jsp,這個modal.jsp裡提供了兩個模態視窗 1. 登入模態視窗 當用戶在未登入狀態,於產品頁點選購買的時候會彈出 2. 刪除模態視窗 當用戶在我的訂單頁面,和購物車頁面進行刪除操作的時候,就會彈出模態刪除視窗。

與後臺一樣,前臺還是採用filter加servlet的方式來簡化配置,在一個ForeServlet類裡,提供所有前端需要用到的業務方法

 ForeServletFilter類充當攔截器的角色

1.假設訪問的路徑是http://localhost:8080/tmall/forehome

2. 在ForeServletFilter 中通過request.getRequestURI()取出訪問的uri: /tmall/forehome

3. 然後截掉/tmall,得到路徑/forehome

4. 判斷其是否以/fore開頭,並且不是/foreServlet開頭

5. 如果是,取出fore之後的值home,並且服務端跳轉到foreServlet

6. 在跳轉之前,還取出了home字串,然後通過request.setAttribute的方式,藉助服務端跳轉,傳遞到foreServlet裡去

ForeServletFilter類程式碼片段(為縮短篇幅簡略了import)

package tmall.filter;
 
public class ForeServletFilter implements Filter{
     
    @Override
    public void destroy() {
         
    }
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String contextPath=request.getServletContext().getContextPath();
        request.getServletContext().setAttribute("contextPath", contextPath);
         //用於顯示頁頭中購物車中物品件數
        User user =(User) request.getSession().getAttribute("user");
        int cartTotalItemNumber= 0;
        if(null!=user){
            List<OrderItem> ois = new OrderItemDAO().listByUser(user.getId());
            for (OrderItem oi : ois) {
                cartTotalItemNumber+=oi.getNumber();
            }
        }
        request.setAttribute("cartTotalItemNumber", cartTotalItemNumber);
         //用於簡易搜尋欄中分類的顯示
        List<Category> cs=(List<Category>) request.getAttribute("cs");
        if(null==cs){
            cs=new CategoryDAO().list();
            request.setAttribute("cs", cs);        
        }
        //對訪問的地址裁剪拼接傳遞到foreServlet中
        String uri = request.getRequestURI();
        uri =StringUtils.remove(uri, contextPath);
        if(uri.startsWith("/fore")&&!uri.startsWith("/foreServlet")){
            String method = StringUtils.substringAfterLast(uri,"/fore" );
            request.setAttribute("method", method);
            req.getRequestDispatcher("/foreServlet").forward(request, response);
            return;
        }
         
        chain.doFilter(request, response);
    }
 
    @Override
    public void init(FilterConfig arg0) throws ServletException {
         
    }
     
}

BaseForeServlet 類,和後臺一樣,也是利用反射,對ForeServlet中的方法進行呼叫,當有擴充套件需求的時候,在ForeServlet中增加一個方法即可。

package tmall.servlet;
 
import java.lang.reflect.Method;
 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import tmall.dao.CategoryDAO;
import tmall.dao.OrderDAO;
import tmall.dao.OrderItemDAO;
import tmall.dao.ProductDAO;
import tmall.dao.ProductImageDAO;
import tmall.dao.PropertyDAO;
import tmall.dao.PropertyValueDAO;
import tmall.dao.ReviewDAO;
import tmall.dao.UserDAO;
import tmall.util.Page;
 
public class BaseForeServlet extends HttpServlet{
 
    protected CategoryDAO categoryDAO = new CategoryDAO();
    protected OrderDAO orderDAO = new OrderDAO();
    protected OrderItemDAO orderItemDAO = new OrderItemDAO();
    protected ProductDAO productDAO = new ProductDAO();
    protected ProductImageDAO productImageDAO = new ProductImageDAO();
    protected PropertyDAO propertyDAO = new PropertyDAO();
    protected PropertyValueDAO propertyValueDAO = new PropertyValueDAO();
    protected ReviewDAO reviewDAO = new ReviewDAO();
    protected UserDAO userDAO = new UserDAO();
     
    public void service(HttpServletRequest request, HttpServletResponse response) {
        try {
             
            int start= 0;
            int count = 10;
            try {
                start = Integer.parseInt(request.getParameter("page.start"));
            } catch (Exception e) {
                 
            }
             
            try {
                count = Integer.parseInt(request.getParameter("page.count"));
            } catch (Exception e) {
            }
             
            Page page = new Page(start,count);
             
            String method = (String) request.getAttribute("method");
 
            Method m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class,
                    javax.servlet.http.HttpServletResponse.class,Page.class);
             
            String redirect = m.invoke(this,request, response,page).toString();
             
            if(redirect.startsWith("@"))
                response.sendRedirect(redirect.substring(1));
            else if(redirect.startsWith("%"))
                response.getWriter().print(redirect.substring(1));
            else
                request.getRequestDispatcher(redirect).forward(request, response);
             
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

在使用者進行訪問,如何判斷使用者是否有登入呢?這裡可以再定義一個攔截器,當訪問那些需要登入才能做的頁面的時候,進行是否登入的判斷,如果不通過,那麼就跳轉到login.jsp頁面去,提示使用者登入。這個攔截器就判斷如果不是註冊,登入,產品這些,就進行登入校驗

1. 準備字串陣列 noNeedAuthPage,存放哪些不需要登入也能訪問的路徑 2. 獲取uri 3. 去掉字首/tmall 4. 如果訪問的地址是/fore開頭,又不是/foreServlet   4.1 取出fore後面的字串,比如是forecart,那麼就取出cart   4.2 判斷cart是否是在noNeedAuthPage    4.2 如果不在,那麼就需要進行是否登入驗證   4.3 從session中取出"user"物件   4.4 如果物件不存在,就客戶端跳轉到login.jsp   4.5 否則就正常執行

package tmall.filter;
 
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.lang.StringUtils;
 
import tmall.bean.OrderItem;
import tmall.bean.User;
import tmall.dao.OrderItemDAO;
 
public class ForeAuthFilter implements Filter{
     
    @Override
    public void destroy() {
         
    }
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String contextPath=request.getServletContext().getContextPath();
 
        String[] noNeedAuthPage = new String[]{
                "homepage",
                "checkLogin",
                "register",
                "loginAjax",
                "login",
                "product",
                "category",
                "search"};
         
        String uri = request.getRequestURI();
        uri =StringUtils.remove(uri, contextPath);
        if(uri.startsWith("/fore")&&!uri.startsWith("/foreServlet")){
            String method = StringUtils.substringAfterLast(uri,"/fore" );
            if(!Arrays.asList(noNeedAuthPage).contains(method)){
                User user =(User) request.getSession().getAttribute("user");
                if(null==user){
                    response.sendRedirect("login.jsp");
                    return;
                }
            }
        }
         
        chain.doFilter(request, response);
    }
 
    @Override
    public void init(FilterConfig arg0) throws ServletException {
         
    }
     
}

注:在web.xml中配置時,ForeAuthFilter必須在ForeServletFilter之前

本篇介紹的是前臺功能實現的一些基礎配置,後面將對其他功能進行開發。