【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之前
本篇介紹的是前臺功能實現的一些基礎配置,後面將對其他功能進行開發。