基于servlet和jsp的shop项目

基于servlet和jsp的shop项目

一、项目开发流程

1.数据库分析

在这里插入图片描述

2.环境搭建

导包,配置文件,导入静态页面,导入工具类,创建项目包结构

二、注册

1.编写user实体类

public class User {

       private String uid;

       private String username;

       private String password;

       private String name;

       private String email;

       private String telephone;

       private Date birthday;

       private String sex;

       private int state;//0--未激活 1--激活

       private String code;//激活码
       
       set get 方法省略
 }      

2.修改静态页面register.jsp

<form class="form-horizontal" action="${pageContext.request.contextPath}/registerServlet" method="post" style="margin-top: 5px;">
					<div class="form-group">
						<label for="username" class="col-sm-2 control-label">用户名</label>
						<div class="col-sm-6">
							<input type="text" class="form-control" id="username" name="username"
								placeholder="请输入用户名">

3.编写servlet和service

将表单提交到registerServlet ,在web包中创建RegisterServlet,并将路径改为registerServlet

在register()方法中 (此时用了状态分发)

首先用request将编码转化为utf-8;

创建一个User对象,用来存储从前台register.jsp 中获取的表单数据

因为从表单中获取的数据是字符串类型,所以需要用注册转化器将String类型转化为Date类型

将从表单中获取的数据通过BeanUtils.populate()方法封装到User对象中

此时再设置User对象的uid和激活码code

再调用service层中的RegisterService类中的regist()方法,将user插入到数据库中

注册成功的话就就需要用邮件激活用户的激活码

通过调用MailUtils中的sendMail()方法发送邮件,通过点击链接跳转到RegisterServlet的activeCode方法来更改激活码的状态

并跳转到注册成功的页面,在注册成功的页面是邮箱,接受发过来的邮件激活激活码,并重定向到login.jsp页面

否则就返回注册失败页面。

RegisterServlet.java

public class registerServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	RegisterService rs=new RegisterService();
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String state=request.getParameter("state");
		if (state.equals("register")) {
			register(request, response);
		}else if (state.equals("activeCode")) {
			activeCode(request, response);
		}
	
	}
protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");		
		User user =new User ();			
		try {		
			//1.手动将String转化Date类型(BeanUtils包下的注册转化器,将String类型转化为Date类型)
			ConvertUtils.register(new Converter(){			
				public Date convert(Class clazz,Object value){
					SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
					Date desc=null;				
					try {
						desc= sf.parse((String)value);
					} catch (ParseException e) {
						e.printStackTrace();
					}
					return desc;				
                    }
			}, Date.class);			
			//2. 组成USer实体对象
			BeanUtils.populate(user, request.getParameterMap());
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
		String code = StringUtils.getUUID();
		user.setUid(StringUtils.getUUID());
		user.setCode(code);
		RegisterService rs=new RegisterService();
		boolean isSucess = rs.regist(user);		
		if (isSucess==true ) {
			//发送邮件,激活用户
			String emailMsg="恭喜你,注册成功,点击下面的连接进行账户激活<br>"				
				+"<a href='http://localhost:8080/shop02/active?activeCode="+code+"'>http://localhost:8080/shop02/active?activeCode="+code+"</a>";
			try {				
				MailUtils.sendMail(user.getEmail(), emailMsg);
			} catch (AddressException e) {
				e.printStackTrace();
			} catch (MessagingException e) {
				e.printStackTrace();
			}				
			 //跳转成功页面
			response.sendRedirect(request.getContextPath()+"/registerSuccess.jsp");
		}else {
			request.setAttribute("msg", "注册失败,重新注册!");		
			request.getRequestDispatcher("/register.jsp").forward(request, response);
		}		
	}
protected void activeCode(HttpServletRequest request, HttpServletResponse response) throws 			ServletException, IOException {
        String code = request.getParameter("activeCode");	
        if (rs.activeCode(code)) {
        // 跳转到登录页面
        response.sendRedirect(request.getContextPath() + "/login.jsp");
        } else {
        // 激活失败
        response.sendRedirect(request.getContextPath() + "/error.jsp");
        }
        }

RegisterService.java

BaseDao dao =new BaseDao();	
	//注册方法
	public boolean  regist(User user ){		
		String sql="insert into user values(?,?,?,?,?,?,?,?,?,?)";
		Object[] params={user.getUid(),user.getUsername(),user.getPassword(),
				user.getName(),user.getEmail(),user.getTelephone(),user.getBirthday(),
				user.getSex(),user.getState(),user.getCode()};		
		int i = dao.updata(sql, params);		
		return i>0?true:false;		
	}
	//激活激活码
	public boolean activeCode(String code){
		String sql="update user set state =1 where code=?";
		Object[] params={code};
		int i=dao.updata(sql,params );
		return i>0?true:false ;
	}

4.ajax校验

而此时在前端还需要进行ajax校验,首先要引入校验插件

<script src="js/jquery.validate.min.js" type="text/javascript"></script>

首先要自定义一个用户名验证是够重复的校验方法,代码如下

<script type="text/javascript">
	//自定义校验规则
	$.validator.addMethod(
			"checkUsername",//自定义校验规则的名称
			function(value,element,params){//自定义校验规则的实现
				//value)表单元素值
				//element)校验的元素对象
				//params)校验规则输入的参数			
				var flag = true;			
				//发送一个Ajax,到服务器进行验证用户存在
				$.ajax({
					"async":false,//同步操作
					"url":"${pageContext.request.contextPath}/user/CheckUser",
					"type":"POST",
					"data":{"username":value},
					"dataType":"json",
					"success":function(data){
					flag = data.isExist;//true--存在  false--不存在
					}
				});			
				//需要返回值 false----该校验器校验失败    true---校验通过			
				return !flag;			
			}		
	)
	$(function(){
		
		$("#registForm").validate({
			rules:{
				"username":{
					"required":true,
					"checkUsername":true
				},
				"password":{
					"required":true,
					"rangelength":[6,12]
				},
				"confirmpwd":{
					"required":true,
					"rangelength":[6,12],
					"equalTo":"#password"
				},
				"email":{
					"required":true,
					"email":true
				},
				"telephone":{
					"required":true
				},
				"name":{
					"required":true
				},
				"birthday":{
					"required":true,
					"date":true
				},
				"sex":{
					"required":true
				}
			},
			messages:{
				"username":{
					"required":"用户名不能为空",
					"checkUsername":"该用户已存在"
				},
				"password":{
					"required":"密码不能为空",
					"rangelength":"密码长度在6-12位"
				},
				"confirmpwd":{
					"required":"确认密码不能为空",
					"rangelength":"确认密码长度在6-12位",
					"equalTo":"两次密码不一致"
				},
				"email":{
					"required":"邮箱不能为空",
					"email":"邮箱格式不正确"
				},
				"telephone":{
					"required":"电话不能为空"
				},
				"name":{
					"required":"真实姓名不能为空"
				},
				"birthday":{
					"required":"生日不能为空",
					"date":"日期格式不正确"
				},
				"sex":{
					"required":"性别必须选择"
				}
			},
			errorPlacement: function (error, element) { //指定错误信息位置
			      if (element.is(':radio') || element.is(':checkbox')) { //如果是radio或checkbox	
			       error.appendTo(element.parent().parent()); //将错误信息添加当前元素的父结点后面
			     } else {
			       error.insertAfter(element);
			     }
			   }
		}); 
	})
</script>

三、登录

1.修改login.jsp页面

将login.jsp页面的登录表单提交到login/LoginServlet 并且验证码的地方生成动态验证码

<font>会员登录</font>USER LOGIN
<div>&nbsp;</div>
<!-- 要提交给处理注册的servlet -->
<form action="${root}/login/LoginServlet" method="post" class="form-horizontal">

<div class="form-group">
	<label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
		<div class="col-sm-3">
			<input type="text" class="form-control" id="inputPassword3"
						placeholder="请输入验证码" name="checkcode">
		</div>
		<div class="col-sm-3">
			<!-- 修改验证码。 动态的验证码 。-->
			<img src="${root}/login/checkcode" onclick="changeImg(this)"/>
		</div>
</div>
<div class="form-group">
	<div class="col-sm-offset-2 col-sm-10">
		<div class="checkbox">
			<label> </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <label> <input type="checkbox" onclick="r(this)" value="off" name="remember"> 自动登录 <span style="color: red">${msg }${msg2 }</span>
			</label>
		</div>
	</div>
</div>


<script>
	//obj就代表了你传入的图片对象。
	function changeImg(obj){
		//alert(obj);
		//注意 当前参数改变的时候 才会重新去请求你的Servlet...
		obj.src="${root}/login/checkcode?a="+new Date().getTime();
	}
	function r(obj){
		if(obj.checked==true)
			obj.value="on";
		else
			obj.value="off";
	}
</script>

2.编写LoginServlet

获取表单中的数据通过BeanUtils封装到User对象中

检查user对象的username和password是否和数据库中的数据一致,并且要判断激活码是否为1 ,为1 的时候才能登录,这里还要实现一个记住密码的功能,用的是cookie技术,将用户名和密码放到cookie中 ,同时还创建一个过滤器,如果发现cookie中有username和password两个cookie,并且和数据库里的数据一致,那么将自动登录,在配置web中url-pattern中要过滤login.jsp(所谓的登录,就是user对象放入到session域中,自动登录就是从cookie中获取user,放入到session域中)

LoginServlet.java

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		Map<String, String[]> parameterMap = request.getParameterMap();	
		User user=new User();	
		try {
			//将表单中的数据封装到user对象中去
			BeanUtils.populate(user, parameterMap);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}	
		String username = user.getUsername();
		String password = user.getPassword();
		HttpSession session = request.getSession();
		LoginService service=new LoginService();
		User checkUser = service.getUser(username, password);		
		String  checkcode1= request.getParameter("checkcode");		
		String checkcode2 = (String) session.getAttribute("checkcode");		
		if (!checkcode1.equalsIgnoreCase(checkcode2)) {
			request.setAttribute("msg", "验证码错误");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
			return ;
		}else{	
			if (checkUser==null) {
				request.setAttribute("msg", "用户名或者密码错误");
				request.getRequestDispatcher("/login.jsp").forward(request, response);
				return ;
			}else if(checkUser.getState()==1&&checkUser!=null){			
				String remember = request.getParameter("remember");			
				if ( remember!=null&&remember.equals("on")) {
					//需要记住名字。密码
					Cookie username_cookie=new Cookie ("username",username);
					Cookie passWord_cookie=new Cookie("password",password);
					username_cookie.setPath("/");
					username_cookie.setMaxAge(60*60*24);
					response.addCookie(username_cookie);
					passWord_cookie.setPath("/");
					passWord_cookie.setMaxAge(60*60*24);
					response.addCookie(passWord_cookie);
				}		
				session.setAttribute("user", checkUser);
				response.sendRedirect(request.getContextPath()+"/index.jsp");		
			}else if (checkUser!=null&&checkUser.getState()==0) {
				request.setAttribute("msg", "用户没有激活");
				request.getRequestDispatcher("/login.jsp").forward(request, response);
			}
		}
	}

loginFilter.java

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {	
		//写一个过滤器  来拦截index.jsp  和 login.jsp  . 
		//先判断当前请求参数中是否携带有cookie...
		//cookie的形式呢  就是email=a     
		//根据你发送过来的cookie中的用户名,查到当前用户中所有的数据,让后将查询到的结果放入到sessio中 
		HttpServletRequest request=(HttpServletRequest) req;		
		HttpServletResponse response=(HttpServletResponse) resp;	
		User user = (User) request.getSession().getAttribute("user");
		if (user == null) {
			String cookie_username = null;
			String cookie_password = null;
			// 获取携带用户名和密码cookie
			Cookie[] cookies = request.getCookies();
			if (cookies != null) {
				for (Cookie cookie : cookies) {
					// 获得想要的cookie
					if ("username".equals(cookie.getName())) {
						cookie_username = cookie.getValue();
					}
					if ("password".equals(cookie.getName())) {
						cookie_password = cookie.getValue();
					}
				}
			}
			if (cookie_username != null && cookie_password != null) {
				// 去数据库校验该用户名和密码是否正确
				LoginService service = new LoginService();
				user = service.getUserByCookie(cookie_username, cookie_password);
				// 完成自动登录
				request.getSession().setAttribute("user", user);			
			}
		}	
		chain.doFilter(request, response);
	}

LoginService.java

public class LoginService {
	private BaseDao <User> dao=new BaseDao<User>();	
	public User getUser(String username,String password){		
		String sql="select * from user where username=? and password=?";		
		Object[] params={username,password};		
		User user =(User) dao.getByOne(sql, params, new User());
		return user;		
	}	
	public User getUserByCookie(String username ,String password){
		String sql="select * from user where username=? and password=?";		
		Object[] params={username,password};	
		User user =(User) dao.getByOne(sql, params, new User());
		return user;
	}
	public boolean checkUser(String username){
		String sql="select * from user where username=?";
		Object[] params={username};
		User byOne = (User) dao.getByOne(sql, params, new User());		
		return byOne==null?false:true;
	}
}

3.前端页面登录状态

此时还要在前端页面将用户名显示出来,来提示当前是登录状态

用c标签需要引入c标签的包

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<c:if test="${empty user }">
		<li><a href="${root}/login.jsp">登录</a></li>
		<li><a href="${root}/register.jsp">注册</a></li>
</c:if>
<c:if test="${not empty user }">
		<li><a href="user.jsp">${user.username}</a></li>
		<li><a href="${root}/LonginOutServlet">注销</a></li>
</c:if>

而注销的功能跳转到了LonginOutServlet中

首先移除session域中的user对象,如果是自动登录,那就需要将cookie移除掉

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		
		session.removeAttribute("user");
		session.invalidate();
		Cookie username_cookie = new Cookie("username", "");
		username_cookie.setMaxAge(0);
		System.out.println("--------------------");
		// 创建存储密码的cookie
		Cookie passWord_cookie = new Cookie("password", "");
		passWord_cookie.setMaxAge(0);
		Cookie pid = new Cookie("pids", "");
		pid.setMaxAge(0);
		response.addCookie(username_cookie);
		response.addCookie(passWord_cookie);
		response.addCookie(pid);
		System.out.println(username_cookie.getName()+"---======-"+username_cookie.getValue());
		
		response.sendRedirect(request.getContextPath()+"/login.jsp");
	}

四、index页面

1.index.jsp页面的最新最热商品

需要一个过滤器,只要访问index.jsp 页面,就将查询到的最新最热商品放到request域中,并将数据在前台页面中展现出来 url-patten 改写成index.jsp

public class IndexFilter implements Filter {
   IndexService is=new IndexService();
	public void destroy() {
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 			throws IOException, ServletException {
		List<Product> hotShop = is.getHot();
		List<Product> newShop = is.getNew();
		request.setAttribute("hotShop", hotShop);
		request.setAttribute("newShop", newShop);
		//request.getRequestDispatcher("/index.jsp").forward(request, response);
		chain.doFilter(request, response);
	}
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}
}

index页面

	<!-- 热门商品 -->
<div class="container-fluid">
	<div class="col-md-12">
		<h2>热门商品&nbsp;&nbsp;<img src="${root }/img/title2.jpg"/></h2>
	</div>
	<div class="col-md-2" style="border:1px solid #E7E7E7;border-right:0;padding:0;">
		<img src="${root }/products/hao/big01.jpg" width="205" height="404" style="display: inline-block;"/>
	</div>
					
<div class="col-md-10">
	<div class="col-md-6" style="text-align:center;height:200px;padding:0px;">
		<a href="product_info.htm">
		<img src="${root }/products/hao/middle01.jpg" width="516px" height="200px" style="display: inline-block;">
		</a>
	</div>
	<c:forEach items="${hotShop }" var="hotShop">
		<div class="col-md-2" style="text-align:center;height:200px;padding:10px 0px;">
			<a href="product_info.htm">
			<img src="${root }/${hotShop.pimage}" width="130" height="130" style="display: inline-block;">
			</a>
			<p><a href="product_info.html" style='color:#666'>${hotShop.pname}</a></p>
			<p><font color="#E4393C" style="font-size:16px">&yen;${hotShop.shop_price}</font></p>
		</div>			
	</c:forEach>				
	/div>
</div>


最新商品代码省略,与最热商品一样

2.分类列表

通过ajax技术将商品分类展示到前台页面上,url跳转到IndexProductServlet?state=categoryList中去获取总的商品分类。

<script type="text/javascript">	
	$(function(){
		var content="";
		//发送AJAX请求  到后台服务器获取数据
		$.post(				
			"${root}/index/IndexProductServlet?state=categoryList",
			function(data){
				//解析date  将数据绑定到页面中		
				for (var i = 0; i < data.length; i++) {
					content+="<li><a href='${root}/index/IndexProductServlet?state=productList&page=1&cid="+data[i].cid+"'>"+data[i].cname+"</a></li>";				
				}			
				//动态绑定到页面中
				$("#categoryUl").html(content);
			},
			"json"			
		);
	});

</script>

protected void categoryList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		List<Category> list = as.queryCategory();
		Gson gson=new Gson();
		String json = gson.toJson(list);
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().write(json);
	}

3.商品列表分页

每一个商品列表是a标签,要跳转的页面是/index/IndexProductServlet?state=productList 同时要传入page参数和商品分类cid,于此同时要创建一个pageBean的类,将分页页面封装到pageBean类中

在这里插入图片描述

public class PageBean<T> {
	private int pageNumber;//当前页
	private int pageSize;//每页显示的条数
	private int totalDataNUmber;//总记录条数
	/*需要计算的数据 */
	private int totalPage;//总页数
	/*需要查询数据的索引*/
	private int startIndex;//开始的数据索引 limit startIndex , pageSize;
	//分页显示的页数    页面显示1,2,3,4,5  页   则开始start=1 end=5
	/**前台开始数字*/
	private int start;
	/**前台结束数字*/
	private int end;	
	//需要在当前页展示的数据
	private List<T> data;	
	private String cid;//cid是商品分类的cid
	//初始化
	public PageBean(int pageNumber, int pageSize, int totalDataNUmber) {
		super();
		this.pageNumber = pageNumber;
		this.pageSize = pageSize;
		this.totalDataNUmber = totalDataNUmber;
		
		//计算总的页数
		if (totalDataNUmber%pageSize==0) {
			totalPage=totalDataNUmber/pageSize;
		}else {
			totalPage=totalDataNUmber/pageSize+1;
		}
		
		//计算开始的索引 (已经显示了的数据)
		startIndex=(pageNumber-1)*pageSize;
		//(页面上要显示的数字区域,唯一有点小绕的地方。)
		//计算页面上要显示的开始跟结束下标。以默认每页显示5页为例。
		start=1;//默认从第一页开始
		end=5;//默认到第五页结束
		if(totalPage<=5){
			//如果总页数不足5页那么刚好  结束数字
			end=totalPage;
		}else{
			//否则就是页面上要显示的页数大于5页。要根据当前页来判断start跟end
			start=pageNumber-2;
			end=pageNumber+2;
			if(start<=0){
				//如果开始位置<=0,则表示是第一页或者第二页还正常显示1,2,3,4,5    不适用上面的加减规则
				start=1;
				end=5;
			}
			if(end>=totalPage){
				//如果结束位置+2后大于总页数,则表示当前页是倒数第二页或者倒数第一页,不适用上面的加减规则
				start=totalPage-4;
				end=totalPage;
			}
		}
	}
get set 方法省略

}	

在productList方法中要获取传入的两个参数,在数据库中拿到每个分类下的总商品数量,然后new一个pageBean对象,将当前的页数和每页要显示的商品数,和每个分类下总的商品数量传入进去。通过商品分类的cid和pageBean中的当前页和当前页显示的商品数量查到每页的商品列表,将商品列表和cid封装到pageBean中

最后将pageBean对象放到session中,并请求转发到商品列表页面,

在页面中展示数据

protected void productList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		String cid = request.getParameter("cid");
		String i = request.getParameter("page");
		//List<Product> productList1 = ps.getProByCid(cid);
		BaseDao dao=new BaseDao();
		//拿到每个分类的product数据量
		int countByCid = dao.getCountByCid(cid);
		//将当前页 每页显示的数据  总的数据数传入到pageBean构造器中
		PageBean pageBean =new PageBean(Integer.parseInt(i),6,countByCid);	
		//拿到分页查询的结果
		List<Product> productList = ps.getProductListByLimit(cid,pageBean );
		//将数据放到session中
		pageBean.setData(productList);
		pageBean.setCid(cid);
		request.getSession().setAttribute("pageBean", pageBean);				
		request.getRequestDispatcher("/product_list.jsp").forward(request, response);
	}

public List<Product> getProductListByLimit(String cid,PageBean pageBean) {		
		String sql="select * from product where cid=? limit ?,?";		
		Object [] params={cid ,pageBean.getStartIndex(),pageBean.getPageSize()};		
		List<Product> list = (List<Product>) dao.getList(sql, params, new Product());
		return list;	
		
	}

		<c:forEach items="${pageBean.data }" var="product">
				<div class="col-md-2" style="height: 230px">
					<a href="${root }/index/IndexProductServlet?state=productInfo&pid=${product.pid}&cid=${product.cid}&page=${pageBean.pageNumber}"> <img src="${root }/${product.pimage}"
						width="170" height="170" style="display: inline-block;">
					</a>
					<p>
						<a href="${root }/index/IndexProductServlet?state=productInfo&pid=${product.pid}&cid=${product.cid}&page=${pageBean.pageNumber}" style='color: green'>${product.pname }</a>
					</p>
					<p>
						<font color="#FF0000">商城价:&yen;${product.shop_price }</font>
					</p>
				</div>
					
				
			</c:forEach>

	</div>

	<!--分页 -->
	<div style="width: 380px; margin: 0 auto; margin-top: 50px;">
		<ul class="pagination" style="text-align: center; margin-top: 10px;">
			<li>
				<a href="${root }/index/IndexProductServlet?state=page&page=1&cid=${pageBean.cid}" aria-label="Previous" >
					<span aria-hidden="true">首页</span>
				</a>
			</li>			
			<c:if test="${pageBean.pageNumber==1}">
				<li class="disabled">
					<a href="javascript:void(0);" aria-label="Previous">
						<span aria-hidden="true">&laquo;</span>
					</a>
				</li>
			</c:if>
			<c:if test="${pageBean.pageNumber!=1}">
				<li>
					<a href="${root }/index/IndexProductServlet?state=page&page=${pageBean.pageNumber-1}&cid=${pageBean.cid}" aria-label="Previous" >
						<span aria-hidden="true">&laquo;</span>
					</a>
				</li>
			</c:if>			
			
			<c:forEach begin="${pageBean.start}" end="${pageBean.end}" step="1" var="i"> 
			  <li <c:if test="${i == pageBean.pageNumber }"> class="active"</c:if>>
			  	<a href="${root}/index/IndexProductServlet?state=page&page=${i}&cid=${pageBean.cid}">${i}</a>
			  </li>
			</c:forEach>
			
			
			<c:if test="${pageBean.pageNumber==pageBean.totalPage}">
				<li class="disabled">
					<a href="javascript:void(0);" aria-label="Next">
						<span aria-hidden="true">&raquo;</span>
					</a>
				</li>
			</c:if>
			
			 <c:if test="${pageBean.pageNumber!=pageBean.totalPage}">
				<li>
					<a href="${root }/index/IndexProductServlet?state=page&page=${pageBean.pageNumber+1}&cid=${pageBean.cid}" aria-label="Next" >
						<span aria-hidden="true">&raquo;</span>
					</a>
				</li>
			</c:if> 			
			
			<li>
				<a href="${root}/index/IndexProductServlestate=page&page=${pageBean.totalPage}&cid=${pageBean.cid}" aria-label="Next">
					<span aria-hidden="true">尾页</span>
				</a>
			</li>
		</ul>
	</div>
	<!-- 分页结束 -->

在前端页面的分页中,要进行判断,若是第一页或者最后一页,不能点击,点击上一页或者下一页的时候,传入的page要减一或者加一,首页和尾页,传入的page参数要等于1或者总的页数

4.商品详情+浏览记录

每个商品跳转到

${root }/index/IndexProductServlet?state=productInfo&pid=${product.pid}&cid=${product.cid}&page=${pageBean.pageNumber}

传入商品id ,商品分类cid 和当前商品的页码,此时还需要做一个返回商品列表,将浏览的商品展示到浏览记录中

在这里用的是cookie技术,将浏览的商品的pid存放到cookie中。先获取cookie,如果cookie中有名为pids的cookie,那么将现在浏览的商品的pid加进去,用“,”隔开,这里先判断是否有这个商品,如果有移除,重新添加,将pids转化成字符串数组,再将字符串数组转化为ArrayList,再转化为LinkedList这样方便操作数据,将现在浏览的商品id添加到第一个。

private void productInfo(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		String pid = request.getParameter("pid");
		Product product = ps.getPro(pid);
		String cid = request.getParameter("cid");
		String page = request.getParameter("page");
		String pids=pid;
		Cookie [] cookies =request.getCookies();
		if (cookies!=null) {		
			for (Cookie cookie : cookies) {
				if ("pids".equals(cookie.getName())) {
					pids=cookie.getValue();
					//获取cookie的值后转化为字符串
					String[] str = pids.split(",");
					//将数据转化为LinkedList 操作更简便
					List<String> asList = Arrays.asList(str);
					LinkedList <String> list= new LinkedList<String >(asList);
					
					if (list.contains(pid)) {
						list.remove(pid);
					}
					//无论充不重复都要添加在起始位置
					list.addFirst(pid);
					StringBuffer sb=new StringBuffer();
					for (int i = 0; i < list.size()&&i<7; i++) {
						sb.append(list.get(i));
						sb.append(",");
					}
					sb.substring(0,sb.length()-1);
					pids = sb.toString();
				}
			}
		}	
		Cookie cookie=new Cookie("pids",pids);
		response.addCookie(cookie);
		request.setAttribute("cid", cid);
		request.setAttribute("page", page);
		request.setAttribute("product1", product);
		request.getRequestDispatcher("/product_info.jsp").forward(request, response);
		
	}

在前台展示数据

在点击返回商品列表时要继续请求page这个方法,传入page和cid参数

<div><a  href="${root }/index/IndexProductServlet?state=page&page=${page}&cid=${cid}">返回列表</a></div>

protected void page(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		//从前台获取当前页的页码
		String pageNumber = request.getParameter("page");
		String cid = request.getParameter("cid");
		BaseDao dao = new BaseDao();
		int countByCid = dao.getCountByCid(cid);	
		//将当前页的页码 和 每页显示的数据量  和 总的数据量 传入到PageBean中
		PageBean pageBean = new PageBean(Integer.parseInt(pageNumber),6,countByCid);
		//当前页要显示的数据
		List<Product> productListByLimit = ps.getProductListByLimit(cid,pageBean);
		pageBean.setCid(cid);	
		//将当前页显示的数据放到PageBean中
		pageBean.setData(productListByLimit);
		request.getSession().setAttribute("pageBean", pageBean);	
		Cookie[] cookies = request.getCookies();
		List<Product> historyList=new ArrayList<Product>();
		if (cookies!=null) {
			for (Cookie c : cookies) {
				if (c.getName().equals("pids")) {
					String pids = c.getValue();
					System.out.println(pids);
					String[] pidsArr = pids.split(",");
					for (String pid : pidsArr) {
						Product pro = ps.getPro(pid);
						historyList.add(pro);					
					}
				
				}
			}
		}		
		request.getSession().setAttribute("historyList", historyList);		
		response.sendRedirect(request.getContextPath()+"/product_list.jsp");		
		/*
		 * 加入 得到的page==1
		 * 当前页码 pageNumber=1
		 * 获取总的数据量
		 * 将 当前页码 和 每页显示的数据量 总的数据量 传入pageBean中  
		 * 	  在pageBean的构造器中 会执行代码
		 * 		startIndex=(pageNumber-1)*pageSize;  就是要分页时候的下标 limit 0,6;
		 * 		传入的
		 * 再调用service类中的分页方法 获取分页的商品数据,并将数据放到PageBean中 再将pageBean 放到session域中
		 * 最后返回product_list.jsp页面
		 * 
		 * 
		 * 若当前页面page=2时
		 * 
		 */
	}
}	

5购物车

A.添加购物车

这里的购物车功能用的是session技术,会存在一些bug,在商品详情页面的添加购物车中,发送请求到

<script type="text/javascript">

	function addCart() {
		var buyNum=$("#quantity").val();
		window.location="${root}/buy/BuyServlet?state=addCart&pid=${product1.pid}&buyNum="+buyNum;
	}
</script>

传入参数pid和要购买的商品数量
在这里插入图片描述

在此之前要先创建cart类和cartItem类,将页面中的数据封装到两个类里面

public class CartItem {
	
	private Product product;//购物项中的商品
	private int buyNum;//购买商品的数量
	private double subTotal;//商品的小计
	.......
}
public class Cart {	
	//购物车中的所有的购物项集合
	private Map<String ,CartItem> cartItems=new HashMap<String ,CartItem>();	
	//总计
	private double total;
	......
}	

在addCart方法中

protected void addCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String num = request.getParameter("buyNum");
		int buyNum=1;
		String pid = request.getParameter("pid");
		HttpSession session = request.getSession();		
		Product pro = ps.getPro(pid);	
        //判断购买的数量如果<1,那就是非法的,转入错误页面
		if (num!=null) {
			 buyNum = Integer.parseInt(num);
			 if (buyNum<=0) {
				 request.setAttribute("error", "您输入数值"+buyNum+"非法,请核对后再提交");
					//输入数据非法
					request.getRequestDispatcher("/error.jsp").forward(request, response);
					return;
			}
		}
		//合计
		double subTotal=pro.getShop_price()*buyNum;
		//购物车应该从session中获取 如果有则合并到一起,如果没有则创建购物车对象
		Cart cart = (Cart) session.getAttribute("cart");
		double newSubTotal = subTotal;
		if (cart==null) {
			//session中没有cart对象
			cart=new Cart();
		}
		//获取都购物车后判断该商品是否存在
		Map<String, CartItem> cartItems = cart.getCartItems();
		if (cartItems.containsKey(pid)) {
			//存在 ,合并该pid对应的商品的buyNum 和subTotal
			int oldBuyNum=cartItems.get(pid).getBuyNum();
			buyNum+=oldBuyNum;
			//合并小计
			newSubTotal=buyNum*pro.getShop_price();
		}
		//如果不包含该商品,就将该商品封装到cartItem中,并添加到cart里面
		CartItem cartItem=new CartItem(pro,buyNum,newSubTotal);
		cart.getCartItems().put(pid, cartItem)	;
		cart.setTotal(cart.getTotal()+subTotal);
		session.setAttribute("cart", cart);
		
		response.sendRedirect(request.getContextPath()+"/cart.jsp");
	}

再在前端页面获取数据,并展示数据

<c:forEach items="${cart.cartItems }" var="cartItem">
							
								<tr class="active">
									<td width="60" width="40%">
										<input type="hidden" name="id" value="22">
										<img src="${root }/${cartItem.value.product.pimage}" width="70" height="60">
									</td>
									<td width="30%">
										<a target="_blank">${cartItem.value.product.pname}</a>
									</td>
									<td width="20%">
										¥${cartItem.value.product.shop_price}
									</td>
									<td width="10%">
									
									 	<input type="text" name="quantity" value="${cartItem.value.buyNum }" maxlength="4" size="10">
								 	</td>
									<td width="15%">
										<span class="subtotal">¥${cartItem.value.subTotal }</span>
									</td>
									<td>
										<a href="javascript:;" class="delete" onclick="delFromCart('${cartItem.value.product.pid}')">删除</a>
									</td>
								</tr>
							</c:forEach>

B.删除购物项

删除之前到用户确认删除,需要用js来实现

<script type="text/javascript">
		
			function delFromCart(pid){
				
				if(confirm("您确定要删除该商品吗?")){
					//跳转到删除的后台
					window.location="${root}/buy/BuyServlet?state=delFromCart&pid="+pid;
				}
			}
			
			function cleanCart(){
				
				if(confirm("您确定要清空购物车吗?")){
					//跳转到删除的后台
					window.location="${root}/buy/BuyServlet?state=cleanCart";
				}
			}
		
		</script>

跳转到删除的方法

protected void delFromCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String pid = request.getParameter("pid");	//得到要删除的商品pid	
		HttpSession session = request.getSession();
		Cart cart = (Cart) session.getAttribute("cart");//获取cart
		Map<String, CartItem> cartItems = cart.getCartItems();	//得到购物车中的购物项集合	
		Set<String> keySet = cartItems.keySet();
		double subTotal=0;
		for (String key : keySet) {//遍历每个购物项
			CartItem cartItem = cartItems.get(key);
			if (cartItem.getProduct().getPid().equals(pid)) {//如果购物项中有这个商品,删除,并拿														//到这里商品项的小计,在之后减去
				cartItems.remove(pid);
				subTotal=cartItem.getSubTotal();
			}
		}			
		cart.setCartItems(cartItems);	
		cart.setTotal(cart.getTotal()-subTotal);//总价中减去删除的商品项的小计
		session.setAttribute("cart", cart);
		request.getRequestDispatcher("/cart.jsp").forward(request, response);	
	}

C.清空购物车

protected void cleanCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		Cart cart = (Cart) session.getAttribute("cart");
		if (cart!=null) {
			session.removeAttribute("cart");
		}
		request.getRequestDispatcher("/cart.jsp").forward(request, response);		
	}

将cart从session中移除掉

6订单

在这里插入图片描述

转入order方法

protected void order(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		LoginService ls=new LoginService();
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		Cart cart = (Cart) session.getAttribute("cart");
		if (user==null) {//首先要判断用户是否登录,没有登录跳转到登录页面
			response.sendRedirect(request.getContextPath()+"/login.jsp");
			return ;
		}
		//先创建一个order类,设置属性
		Order order = new Order();
		order.setOid(StringUtils.getUUID());
		order.setTotal(cart.getTotal());
		order.setOrdertime(new Date());
		order.setUser(user);
		//获取cartItem,将每个购物项的数据转化为orderItem
		Map<String, CartItem> cartItems = cart.getCartItems();
		Set<String> keySet = cartItems.keySet();		
		for (String key : keySet) {
			OrderItem orderItem=new OrderItem();
			//得到每一个购物项
			CartItem cartItem = cartItems.get(key);
			Product pro=cartItem.getProduct();
			orderItem.setItemid(StringUtils.getUUID());
			orderItem.setCount(cartItem.getBuyNum());
			orderItem.setOrder(order);
			orderItem.setProduct(pro);
			orderItem.setSubtotal(cartItem.getSubTotal());		
			order.getOrderItems().add(orderItem);	
		}
		//将封装好数据的order和orderItem插入数据库
		ProductService ps=new ProductService();
		ps.submitOrders(order);
		session.setAttribute("order", order);		
		response.sendRedirect(request.getContextPath()+"/order_info.jsp");
	}


public void submitOrders(Order order) {
		try {
			//1.开启事务
			DataSourceUtils.startTransaction();
			//2.调用dao层的操作order的方法
			addOrders(order);
			//3.调用dao层的操作orderitem的方法
			addOrderItems(order);
		} catch (SQLException e) {
			//事务回滚
			try {
				DataSourceUtils.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			try {
				//提交释放资源
				DataSourceUtils.commitAndRelease();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}	
	public void addOrders(Order order) throws SQLException{
		QueryRunner runner = new QueryRunner();
		String sql = "insert into orders values(?,?,?,?,?,?,?,?)";
		Connection conn = DataSourceUtils.getConnection();
		runner.update(conn, sql, order.getOid(),order.getOrdertime(),order.getTotal(),
	                order.getState(),order.getAddress(),order.getName(),
	                order.getTelephone(),order.getUser().getUid());		
	}
	public void addOrderItems(Order order) throws SQLException{	
		QueryRunner runner = new QueryRunner();
		Connection conn;
			conn = DataSourceUtils.getConnection();
			for(OrderItem item : order.getOrderItems())
			{
				String sql = "insert into orderitem values(?,?,?,?,?)";
				runner.update(conn,sql,item.getItemid(),item.getCount(),item.getSubtotal(),
						item.getProduct().getPid(),order.getOid());
			}	
	}

7.提交订单

在订单页面中点击提交订单,此时就需要支付的接口了,这里用的是易宝支付的接口,点击提交订单的时候直接跳转到支付页面

protected void orderForm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//更新用户状态
		HttpSession session = request.getSession();
		Order order = (Order) session.getAttribute("order");//获取订单
		//获取姓名,地址,电话,封装到order里面
		String name = request.getParameter("name");
		String address = request.getParameter("address");
		String phone = request.getParameter("phone");
		order.setAddress(address);
		order.setTelephone(phone);
		order.setName(name);
		ps.updateOrder(order);//更改数据库的数据
		//完成支付功能
		  // 2.完成支付功能
		// 获得 支付必须基本数据
		String orderid = order.getOid();
		String money = "0.01";
		// 银行
		String pd_FrpId = request.getParameter("pd_FrpId");
		// 发给支付公司需要哪些数据
		String p0_Cmd = "Buy";
		String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId");
		String p2_Order = orderid;
		String p3_Amt = money;
		String p4_Cur = "CNY";
		String p5_Pid = "";
		String p6_Pcat = "";
		String p7_Pdesc = "";
		// 支付成功回调地址 ---- 第三方支付公司会访问、用户访问
		// 第三方支付可以访问网址
		String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("callback");
		String p9_SAF = "";
		String pa_MP = "";
		String pr_NeedResponse = "1";
		// 加密hmac 需要密钥
		String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue");
		String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc,
				p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue);
		String url = "https://www.yeepay.com/app-merchant-proxy/node?pd_FrpId=" + pd_FrpId + "&p0_Cmd=" + p0_Cmd
				+ "&p1_MerId=" + p1_MerId + "&p2_Order=" + p2_Order + "&p3_Amt=" + p3_Amt + "&p4_Cur=" + p4_Cur
				+ "&p5_Pid=" + p5_Pid + "&p6_Pcat=" + p6_Pcat + "&p7_Pdesc=" + p7_Pdesc + "&p8_Url=" + p8_Url
				+ "&p9_SAF=" + p9_SAF + "&pa_MP=" + pa_MP + "&pr_NeedResponse=" + pr_NeedResponse + "&hmac=" + hmac;
		// 重定向到第三方支付平台
		response.sendRedirect(url);		
	}

当支付完成之后需要一个回调函数,将数据库中的订单改成已支付的状态

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		
		// 获得回调所有数据
		String p1_MerId = request.getParameter("p1_MerId");
		String r0_Cmd = request.getParameter("r0_Cmd");
		String r1_Code = request.getParameter("r1_Code");
		String r2_TrxId = request.getParameter("r2_TrxId");
		String r3_Amt = request.getParameter("r3_Amt");
		String r4_Cur = request.getParameter("r4_Cur");
		String r5_Pid = request.getParameter("r5_Pid");
		String r6_Order = request.getParameter("r6_Order");
		String r7_Uid = request.getParameter("r7_Uid");
		String r8_MP = request.getParameter("r8_MP");
		String r9_BType = request.getParameter("r9_BType");
		String rb_BankId = request.getParameter("rb_BankId");
		String ro_BankOrderId = request.getParameter("ro_BankOrderId");
		String rp_PayDate = request.getParameter("rp_PayDate");
		String rq_CardNo = request.getParameter("rq_CardNo");
		String ru_Trxtime = request.getParameter("ru_Trxtime");
		// 身份校验 --- 判断是不是支付公司通知你
		String hmac = request.getParameter("hmac");
		String keyValue = ResourceBundle.getBundle("merchantInfo").getString(
				"keyValue");
		// 自己对上面数据进行加密 --- 比较支付公司发过来hamc
		boolean isValid = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd,
				r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid,
				r8_MP, r9_BType, keyValue);
		if (isValid) {
			// 响应数据有效
			if (r9_BType.equals("1")) {			
				ProductService ps=new ProductService();
				ps.updateOrderState(r6_Order);					
				// 浏览器重定向
				response.setContentType("text/html;charset=utf-8");
				response.getWriter().println("<h1>付款成功!等待商城进一步操作!等待收货...</h1>");
			} else if (r9_BType.equals("2")) {
				// 服务器点对点 --- 支付公司通知你
				System.out.println("付款成功!");
				// 修改订单状态 为已付款
				// 回复支付公司
				response.getWriter().print("success");
			}
		} else {
			// 数据无效
			System.out.println("数据被篡改!");
		}

	}

8.我的订单

点击我的订单触发myOrder方法,订单实现了分页功能

首先得page为1

判断user是否为空。为空返回登录页面

 protected void myOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();	
		String page = request.getParameter("page");
		User user = (User) session.getAttribute("user");
		BaseDao dao=new BaseDao();
		if (user==null) {//判断用户是否为空
			response.sendRedirect(request.getContextPath()+"/login.jsp");
			return;
		}
		String uid=user.getUid();
		//拿到用户的总的订单量
		int orderCount = dao.getOrderCount(uid);
        //将当前页码page,每页展示的数据个数,总的数据传入到pageBean中
		PageBean<Order> pageBean=new PageBean<Order>(Integer.parseInt(page),6,orderCount);
		pageBean.setCid(uid);
		//获取该用户的所有订单
		List<Order> orders = ps.getOrders(user.getUid(),pageBean);
		if (orders!=null) {
			for (Order order : orders) {
				//获取每一个订单 根据oid查找订单项集合
				try {
	//sql = "select i.count,i.subtotal,p.pimage,p.pname,p.shop_price from "
	//			+ "orderitem i,product p where i.pid=p.pid and i.oid=?";	
    //获取需要展示的数据,存放到list嵌套Map的集合中
					List<Map<String,Object>> orderItems = ps.getOrderItems(order.getOid());
					for (Map<String, Object> map : orderItems) {
						OrderItem orderItem=new OrderItem();					
						BeanUtils.populate(orderItem, map);	//将数据映射到orderItem中		
						Product pro=new Product();
						BeanUtils.populate(pro, map);//将数据映射到product中				
						orderItem.setProduct(pro);	//Pro添加到orderItem中				
						order.getOrderItems().add(orderItem);//orderItem添加到Order中
					}				
				} catch (SQLException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}				
			}
		}
		pageBean.setData(orders);
		request.setAttribute("pageBean", pageBean);
		request.getRequestDispatcher("/order_list.jsp").forward(request, response);
	}


	public List<Map<String, Object>> getOrderItems(String oid ) throws SQLException{
		QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
		String sql = "select i.count,i.subtotal,p.pimage,p.pname,p.shop_price from "
				+ "orderitem i,product p where i.pid=p.pid and i.oid=?";
		List<Map<String, Object>> listMap = runner.query(sql, new MapListHandler(), oid);
		return listMap;

		
	}

五、后台

后台管理只有三个模块1.分类管理,2.商品管理,3.订单管理,实现的是增删改查的功能

1.登录

数据库中创建admin表,存放管理员信息

简单的登录流程,是简化的前台登录。

2.分类管理

A 分类列表

当点击分类管理时,从数据库中获取商品分类列表展示在list.jsp页面上

public void queryCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{		
		List<Category> categoryList = service.queryCategory();//获取所有的商品分类		
		request.setAttribute("categoryList", categoryList);				
		request.getRequestDispatcher("/admin/category/list.jsp").forward(request, response)	
	}


<c:forEach items="${categoryList }" var="category">
							<tr onmouseover="this.style.backgroundColor = 'white'"
									onmouseout="this.style.backgroundColor = '#F5FAFE';">
									<td style="CURSOR: hand; HEIGHT: 22px" align="center" 
										width="18%">${category.cid }</td>
									<td style="CURSOR: hand; HEIGHT: 22px" align="center"
										width="17%">${category.cname }</td>
									<td align="center" style="HEIGHT: 22px"><a
										href="${ pageContext.request.contextPath }/admin/category/edit.jsp?cid=${category.cid}&cname=${category.cname}">
											<img
											src="${pageContext.request.contextPath}/images/i_edit.gif"
											border="0" style="CURSOR: hand">
									</a></td>
	
									<td align="center" style="HEIGHT: 22px"><a
										href="${pageContext.request.contextPath}/admin/AdminServlet?state=delete&cid=${category.cid}">
											<img src="${pageContext.request.contextPath}/images/i_del.gif"
											width="16" height="16" border="0" style="CURSOR: hand">
									</a></td>
								</tr>
						
						</c:forEach>

B 编辑

当点击编辑的时候,进入编辑页面,并将更改的数据回显到编辑页面(传入参数cid和cname,在edit.jsp页面找显示数据),点击确定是触发edit方法,最后返回商品分类列表

protected void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	  	
		String cname = request.getParameter("cname");
		String cid = request.getParameter("cid");	
		service.updateCategory(cid, cname);		
		queryCategory(request, response);
		
	}

C 删除

protected void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		String cid = request.getParameter("cid");
		service.deleteCategory(cid);
		queryCategory(request, response);
	}

D 添加

点击添加时,进入add.jsp页面,点击确定,将数据添加到数据库,在返回到商品分类列表中

protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		String cname = request.getParameter("cname");
		Category category=new Category();		
		category.setCname(cname);
		category.setCid(StringUtils.getUUID());
		int i=service.insertCategory(category);
		queryCategory(request, response);				
	}

3.商品管理

商品管理中基本的和分类管理一样,应该说的是上传文件,在添加和编辑的时候都涉及到了

下面是添加的代码

protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			// 定义一个文件项工厂类
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 指定一个临时目录缓冲区
			String temp_path = this.getServletContext().getRealPath("temp");
			File file = new File(temp_path);
			if (!file.exists()) {
				file.mkdirs();
			}
			// 设置你的缓冲区大小
			factory.setSizeThreshold(1024 * 1024);
			// 设置缓冲区的位置
			factory.setRepository(file);
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 处理上传乱码的问题
			upload.setHeaderEncoding("utf-8");
			// 创建一个map集合,存储循环遍历数据的名值对
			Map<String, String> map = new HashMap<String, String>();
			//获取所有的表单信息存放到list中
			List<FileItem> parseRequest = upload.parseRequest(request);
			//遍历表单集合
			for (FileItem fileItem : parseRequest) {
				if (fileItem.isFormField()) {// 判断是否是一个普通表单
					//获取表单名name
					String fieldName = fileItem.getFieldName();
					//获取表单值,编码格式转化为utf-8
					String fieldValue = fileItem.getString("utf-8");
					//将表单的信息存放到map集合中
					map.put(fieldName, fieldValue);
				} else {//如果不是普通表单,那就是上传文件
					//拿到表单的name
					String fieldName = fileItem.getFieldName();
					// 拿到要上传文件的文件名
					String fileName = fileItem.getName();
					// 通过输入流拿到数据
					InputStream input = fileItem.getInputStream();
					// 把输入的内容(其实就是你要上的文件,写到指定的位置
					fileItem.write(new File("D:\\newspace\\shop02\\WebContent\\products\\" + fileName));
					// 写完之后,需要知道文件上传到什么位置了
					map.put(fieldName, "products/" + fileName);
					input.close();
					fileItem.delete();
				}
			}
			Product product = new Product();
			BeanUtils.populate(product, map);//将表单中的数据映射到product里面
			product.setPid(StringUtils.getUUID());
			product.setPflag(0);
			product.setPdate(StringUtils.getDate());
			service.insertProduct(product);//将商品存放到数据库中
			queryProduct(request, response);//返回商品列表
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

编辑的代码

protected void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			String pid = request.getParameter("pid");
			String pimage = request.getParameter("pimage");
			// 定义一个文件项工厂类
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 指定一个临时目录缓冲区
			String temp_path = this.getServletContext().getRealPath("temp");
			File file = new File(temp_path);
			if (!file.exists()) {
				file.mkdirs();
			}
			// 设置你的缓冲区大小
			factory.setSizeThreshold(1024 * 1024);
			// 设置缓冲区的位置
			factory.setRepository(file);
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 处理上传乱码的问题
			upload.setHeaderEncoding("utf-8");
			// 创建一个map集合,存储循环遍历数据的名值对
			Map<String, String> map = new HashMap<String, String>();
			List<FileItem> parseRequest = upload.parseRequest(request);
			for (FileItem fileItem : parseRequest) {

				if (fileItem.isFormField()) {// 判断是否是一个普通表单
					String fieldName = fileItem.getFieldName();
					String fieldValue = fileItem.getString("utf-8");
					map.put(fieldName, fieldValue);
				} else {
					String fieldName = fileItem.getFieldName();
					// 拿到要上传文件的文件名
					String fileName = fileItem.getName();
					if (fileName.equals("")) {//如果没有上传文件,就继续用以前的文件
						fileName = pimage;
						map.put(fieldName, fileName);
					} else {//如果上传了文件,就改变以前的图片
						// 通过输入流拿到数据
						InputStream input = fileItem.getInputStream();
						// 把输入的内容(其实就是你要上的文件,写到指定的位置
						fileItem.write(new File("D:\\newspace\\shop02\\WebContent\\products\\" + fileName));
						// 写完之后,需要知道文件上传到什么位置了
						map.put(fieldName, "products/" + fileName);
						input.close();
						fileItem.delete();
					}
				}
			}
			Product product = new Product();
			BeanUtils.populate(product, map);
			product.setPid(pid);
			product.setPflag(0);
			product.setPdate(StringUtils.getDate());
			service.updatePro(product);
			queryProduct(request, response);
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

4.订单管理

订单管理只有查看的功能,可以查看每个订单的订单项,这里用到了ajax技术,当点击订单详情的时候展示出每个订单的订单项,要记得导入插件呢

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String state = request.getParameter("state");
		if (state.equals("orderList")) {
			orderList(request, response);		
		}else if (state.equals("findOrderInfoByOid")) {
			findOrderInfoByOid(request, response);
		}
	}
	protected void orderList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Order> orderList = as.getOrderList();		
		request.setAttribute("orderList", orderList);
		request.getRequestDispatcher("/admin/order/list.jsp").forward(request, response);	
	}
	protected void findOrderInfoByOid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String oid = request.getParameter("oid");
		List<Map<String, Object>> orderItemByOid = as.getOrderItemByOid(oid);
		Gson g=new Gson();
		String json = g.toJson(orderItemByOid);		
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().write(json);	
	}


<script type="text/javascript">
			$(function(){
				//弹出层插件调用
				new PopupLayer({
					trigger:".clickedElement",//触发对象
					popupBlk:"#showDiv",//弹出层是哪个DIV
					closeBtn:"#closeBtn",//关闭弹出层点击哪个元素
					useOverlay:true
				});
				
			});
			function findOrderInfoByOid(oid)
			{
				//清空显示的详情内容
				$("#showDivTab").html("");
				$("#shodDivOid").html(oid);
				//设置加载图片显示
				$("#loading").css({"display":"block"});
				
				
				$.post(
					"${pageContext.request.contextPath}/admin/OrderServlete?state=findOrderInfoByOid",
					{"oid":oid},
					function(data){
						
						$("#loading").css({"display":"none"});
						//[
						//{"shop_price":2299.0,"count":2,"pname":"宏碁(acer)ATC705-N50 台式电脑","pimage":"products/1/c_0031.jpg","subtotal":4598.0},
						//{"shop_price":1299.0,"count":4,"pname":"小米 4c 标准版","pimage":"products/1/c_0001.jpg","subtotal":5196.0},
						//{"shop_price":2298.0,"count":1,"pname":"vivo X5Pro","pimage":"products/1/c_0014.jpg","subtotal":2298.0}
						//]
						var content=
							"<tr id='showTableTitle'>"+
								"<th width='20%'>图片</th>"+
								"<th width='25%'>商品</th>"+
								"<th width='20%'>价格</th>"+
								"<th width='15%'>数量</th>"+
								"<th width='20%'>小计</th>"+
							"</tr>"
						for(var i in data)
						{
							content+="<tr style='text-align: center;'>"+
								"<td><img src='${pageContext.request.contextPath }/"+data[i].pimage+"' width='70' height='60'></td>"+
								"<td><a target='_blank'>"+data[i].pname+"</a></td>"+
								"<td>¥"+data[i].shop_price+"</td>"+
								"<td>"+data[i].count+"</td>"+
								"<td><span class='subtotal'>¥"+data[i].subtotal+"</span></td></tr>";
					}			
						$("#showDivTab").html(content);			
					},
					"json"
				)
			}			
		</script>


	
	public List<Map<String,Object>> getOrderItemByOid(String oid){
		QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
		String sql="select p.pimage,p.pname,p.shop_price,i.count,i.subtotal from orderitem i,product p where i.pid=p.pid and i.oid=?";
		
		List<Map<String,Object>> query=null;
		try {
			query = runner.query(sql, new MapListHandler(), oid);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return query;

		
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值