完成了j2ee商城后台的开发,就到前台了,前台的功能总体来说比后台要多,而且也是包含许多比较常用的业务。将业务分为需要登录才能进行的业务和无需登录也能进行的业务。
无需登录:注册,登录,退出,产品页,模态登录,搜索
需要登录:购买,添加购物车,结算,查看购物车,生产订单,查看订单,评价等
演示地址:http://how2j.cn/tmall/
源码下载地址:https://pan.baidu.com/s/1C56LbKPDPRiBPdedwF638g 密码:enlt
前台主页由五个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 ois = new OrderItemDAO().listByUser(user.getId());
for (OrderItem oi : ois) {
cartTotalItemNumber+=oi.getNumber();
}
}
request.setAttribute("cartTotalItemNumber", cartTotalItemNumber);
//用于简易搜索栏中分类的显示
List cs=(List) 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之前
本篇介绍的是前台功能实现的一些基础配置,后面将对其他功能进行开发。