后台控制

//过滤器已经实现编码问题
String op = request.getParameter("op");
if("addCategory".equals(op)) {
	addCategory(request,response);
} else if("showAllCategories".equals(op)) {
	showAllCategories(request,response);
} else if("addBookUI".equals(op)) {
	addBookUI(request,response);
} else if ("addBook".equals(op)) {
	addBook(request,response);
} else if("showAllBooks".equals(op)) {
	showAllBooks(request,response);
} else if("login".equals(op)) {
	login(request,response);
} else if("managerLogout".equals(op)) {
	managerLogout(request,response);
}		
一、 添加分类(添加分类模块--链接)
	1. 添加分类将表单数据添加到Category中
	2. 调用业务逻辑方法进行添加到数据库中
	3. 添加成功提示
		response.getWriter().write("<font color='green'>保存成功</font>");
	4. 否则
		response.getWriter().write("<font color='red'>保存失败,类别已经存在</font>");
	
二、 显示所有分类(查询分类模块--链接)
	1. 调用业务方法查询所有分类
	2. 将categories设置到request域中
	3. 转发到/manager/showAllCategories.jsp

三、 链接到添加书籍页面(添加图书模块--链接)
	1. 调用业务方法查询所有分类
	2. 将categories设置到request域中
	3. 转发到/manager/addBookUI.jsp

四、 添加书籍(添加图书模块--链接)
	1. 判断是enctype是否是multipart,如果不是提示信息,返回
		response.getWriter().write("请选择正确的enctype类型<a href='"+request.getContextPath()+"/manager/addBookUI.jsp'>返回操作</a>");
	2. 创建文件上传对象,解析请求参数,创建book对象
	3. 遍历解析到的请求对象,如果是普通字段,直接获取字段名和值,通过BeanUtils工具设置到book对象中
	4. 如果不是上传字段
		1). 得到文件名,唯一文件名+扩展名FilenameUtils.getExtension,将文件名设置到book对象中
		2). 获取文件存储路径,如果路径不存在就创建该目录
		3). 构建子目录,将子目录存储到book的path中
		4). 将上传文件写入存储路径中
	5. 	调用业务方法将book添加到数据库中
		request.setAttribute("msg","<script type='text/javascript'>alert('文件保存成功');</script>");
	6. 为了重新获取书籍分类,要重新查所有分类再转发到/manager/addBookUI.jsp

五、 显示书籍(查看图书模块--链接)
	1. 获取请求页码
	2. 调用业务方法查询PageBean对象 findBookPageByPageNum(pageNum)
	3. 设置url地址,pb.setUrl(request.getContextPath()+"/servlet/ManagerServlet?op=showAllBooks");
	4. 将page设置到request域中
	5. 转发到"/manager/listBooks.jsp"

 

前台控制

String op = request.getParameter("op");
if("showIndex".equals(op)) {
	showIndex(request, response);
} else if("listBookByCategory".equals(op)) {
	listBookByCategory(request,response);
} else if("buyBook".equals(op)) {
	buyBook(request,response);
} else if("delOneItem".equals(op)) {
	delOneItem(request,response);
} else if("delMultiItem".equals(op)) {
	delMultiItem(request, response);
} else if("changeItemNum".equals(op)) {
	changeItemNum(request,response);
} else if("regist".equals(op)) {
	regist(request,response);
} else if("active".equals(op)) {
	active(request,response);
} else if("login".equals(op)) {
	login(request,response);
} else if("logout".equals(op)) {
	logout(request,response);
} else if("getOrders".equals(op)) {
	getOrders(request,response);
} else if("showOrders".equals(op)) {
	showOrders(request,response);
} else if("pay".equals(op)) {
	pay(request,response);
} else if("payUI".equals(op)) {
	payUI(request,response);
}
一、 显示前台主页(首页模块-->链接)
	1. 查询所有分类,将分类的集合categories设置到request域中
	2. 获取请求的页码,调用业务方法通过页码查找书籍得到一个PageBean对象
	3. 设置url、设置page到request域中
	4. 转发到listBooks.jsp中
二、 按照分类查询所有书籍
	1. 查询所有分类,将分类的集合categories设置到request域中
	2. 获取请求参数:页码和分类的id(categoryId)
	3. 调用业务方法,查找PageBean对象通过页码和分类id
	4. 设置url、设置request域中对象page
	5. 转发到listBooks.jsp
三、 购买链接
	1. 获取书籍bookId
	2. 调用业务方法通过bookId查找书籍findBookId(bookId)
	3. 获取session,从session域中查找购物车cart
	4. 若cart为空,创建cart对象,将cart设置到session域中
	5. 将书籍添加到购物车中
	6. AJax响应数据,response.getWriter().write("<font color='red'>购买成功,如需查看您购买的物品,请点击购物车</font");
四、 删除单个项目
	1. 获取请求参数bookdId
	2. session域查找cart
	3. 在购物车中移除该bookid
	4. 重定向到showCart.jsp
五、 删除多个项目
	1. 获取请求的ids一个数组
	2. 获取session中的cart
	3. 遍历ids,通过购物车进行移除
	4. 重定向到/showCart.jsp

六、 改变购物项数量
	1. 获取数量和书籍编号num/bookId
	2. 将获取的数量强转一个int类型newNum,要作异常处理
	3. 获取session对象,获取session对象的购物车
	4. 如果购物车不为空,并且购物项大于0
		通过书籍编号查找该购物项,设置该购物项的数量
	5. 重定向到showCart.jsp
七、 注册用户(Customer)
	1. 将请求的注册信息注入到Customer对象中
	2. 设置客户id/code(激活码)
	3. 调用业务方法进行注册用户registCustomer(c)
	4. 注册成功提示信息
		response.getWriter().write(
					"注册成功,激活码已发送到您的" + c.getEmail() + "信件中...");
	5. 如果注册时有异常就对其提示注册失败
	
	#发送邮件
	1. 开启一个SendMail类专用于发送邮件的线程
	2. 构造接收客户信息和请求地址的构造函数
	3. 定义props集合存储协议...
	4. 创建Session、MemeMessage(邮件信息)
	5. 设置发送者、接收类型、主题、内容
		message.setContent("欢迎加入黑马<br/>如需激活您的账户<a href='http://localhost:8080/"+context+"/servlet/ClientServlet?op=active&username="+c.getUsername()+"&code="+c.getCode()+"'>激活</a>欢迎骚扰~", "text/html;charset=UTF-8");
		保存邮件改变信息,message.saveChanges();
	6. 	通过session对象得到一个火箭,设置用户名、密码connect
	7. 设置发送messsage对象,和接受者
	
八、 激活邮件处理
	1. 获取用户名和激活码
	2. 调用业务方法进行激活activedCustomer(username, code)
	3. 提示信息
		response.getWriter().write("激活成功");
		response.setHeader("Refresh", "2;URL="+request.getContextPath());
	4. 否则提示服务器忙

九、 登录操作
	1. 获取用户名、密码请求参数
	2. 调用业务方法进行验证loginCustomer(username, password)
	3. 如果得到的用户为空,提示信息
		response.getWriter().write("提示用户名和密码错误或者未激活,2秒后跳到登录页面");
		response.setHeader("Refresh", "2;URL="+request.getContextPath()+"/login.jsp");
	4. 	否则就将用户customer设置到session域中
	5. 提示登录成功
		response.getWriter().write("登录成功,2秒后跳到主页");
		response.setHeader("Refresh", "2;URL="+request.getContextPath());
十、 注销操作
	1. 移除session域中的用户customer
	2. 提示信息
		response.getWriter().write("注销成功,2秒后跳到登录页");
		response.setHeader("Refresh", "2;URL="+request.getContextPath()+"/login.jsp");
	
十一、 生成订单getOrder
	1. 得到session对象,从session域中查找customer
	2. 如果用户为空跳转
		response.sendRedirect(request.getContextPath()+"/login.jsp");
		return;
	3. 从session域中获取购物车对象
	4. 创建Orders对象
	5. 设置订单号OrdersNum,设置总金额、总数量、设置订单对应的Customer
	6. 遍历购物车中的购物项
	7. 获取每一个购物项
	8. 创建LineItem对象,存储订单明细
	9. 设置订单明细的id,设置数量,小计,设置对应的书籍Book
	
	10. 将订单明细添加到订单中orders
	11. 调用业务方法生成订单信息genOrders(orders);
	12. 将订单设置到request域中,转发到pay.jsp
		request.setAttribute("o", orders);
		request.getRequestDispatcher("/pay.jsp").forward(request, response);
		
十二、 	显示订单(我的订单)showOrders
	1. 从session域中查找customer
	2. 如果customer为空重定向到/login.jsp
	3. 调用业务方法获取所有订单findOrdersByCustomerId(c.getId())
	4. 将订单设置到request域中
	5. 转发到/showCustomerOrders.jsp

 

在线支付

一、 结算购物车商品pay
	1. 获取订单号orderid、金额money、银行类型pd_FrpId
	2. 封装参数
		url="http://localhost:8080/"+request.getContextPath()+"/servlet/PaymentResponse"
		String hmac = PaymentUtil.buildHmac(...);
	3. 将参数设置到request域中,转发到sure.jsp
	4. sure.jsp表单提交到https://www.yeepay.com/app-merchant-proxy/node
	5. 建立PaymentResponse类,获取request域中的值
	6. 验证数据是否有效PaymentUtil.verifyCallback
	7. 如果有效
		r1_Code:1代表成功
		r9_BType:2代表服务器点对点通信,若设置2就必须会写sucess
		if("1".equals(r1_Code)) {
			if("2".equals(r9_BType)) {
				response.getWriter().write("success");
			}
		}
	8. 如果if("1".equals(r1_Code))成功,调用业务方法findOrdersByOrdersNum(r6_Order)
	9. 将查询到的订单修改状态,然后再调用业务方法更新订单
	10. 提示信息
		response.getWriter().write("支付成功!,<a href='http://localhost:8080/"+request.getContextPath()+"/showCustomerOrders.jsp'>点击返回订单页面</a>");

二、 我的订单中(付款操作)
	1. 获取session对象,从session中查找customer
	2. 如果为空跳转到
		response.sendRedirect(request.getContextPath()+"/login.jsp");
		return;
	3. 获取订单号,调用业务方法查询该订单
	4. 将查询到的订单设置到request域中
	5. 转发到/pay.jsp中

 

权限控制

一、 用户登录
	1. 获取请求的参数username&password
	2. 业务层进行验证登录,返回user对象
	3. 判断user是否为空,若不为空设置到session域中
		重定向manager/index.jsp;
	4. 若为空
		response.getWriter().write("错误的用户名或密码,请重新登录");
		跳转到login/login.jsp
		
二、 用户注销
	1. 从session域中移除user对象
	2. 重定向/login/login.jsp
	
#### 权限过滤器(基于URI地址过滤权限问题)
	1. 对于登录、注销、获取Ajax引擎不需要过滤,所以这几个采用直接放行
	2. 获取请求地址getRequestURI(),获取请求参数getQueryString(),如果请求参数不为空,拼接uri地址
	3. 替换应用名为空字符串,为了在后面和权限中的地址做判断
	4. 获取session中的user对象,如果user为空,重定向到后台登录页/login/login.jsp
	5. 创建菜单集合menus,用作存储数据库中查询到的集合
	6. 调用业务方法,通过user查找Role权限集合 service.findUserRoles(user);
	7. 遍历权限集合,然后获得每一个权限对象,通过权限对象获取菜单集合service.findMenuRole(role);
	8. 将查到的菜单集合添加到menus中
	9. 定义一个变量hasPermission,判断是否有该权限
	10. 遍历menus,判断菜单模块中的地址是否和请求的地址是否相等,如果相等设置hasPermission为true,break;
	11. 如果hasPermission为true,直接放行,否则就提示没有权限