您的位置:首页 > 运维架构 > 网站架构

购物网站核心代码_文件上传_发送邮件_购物车设计_在线支付

2013-10-14 22:56 706 查看
2、搭建开发环境
技术要求:
数据库使用MySQL
使用MVC+三层架构的开发模型
DAO:DBUtils框架。请使用数据源
Servlet:充当控制器。Beanutils框架
JSP:充当显示(不能有一行java脚本和代码)
文件上传:fileupload

拷贝jar包:
mysqldriver.jar
commons-dbcp.jar
commons-pool.jar
commons-dbutils.jar
commons-beanutils.jar
commons-logging.jar
commons-fileupload.jar
commons-io.jar
jstl.jar
standard.jar

3、按照需求逐个实现并进行测试
1.添加分类-----》addCategory.jsp----》调用方法将数据保存
2.遍历分类-----》showAllcategory----》调用方法将数据遍历出来
3.添加书籍-----》addBook.jsp-----》书分类到分类下面
难点:1.要上传图片,用form表单上传图片的方式enctype=multipart/form-data
<form action="" method="post" enctype="multipart/form-data">
<td>图片</td>
    <td>
    <input type="file" name="image">
    </td>
2.所属分类用监听器控制,session监听器,查出分类信息,在页面用session域中的参数
public class QueryAllCategoryListener implements HttpSessionListener {
private BusinessService s = new BusinessServiceImp();
public void sessionCreated(HttpSessionEvent sees) {
HttpSession session =sees.getSession();
//查询到所有分类,存放到session中
List<Category> Categorys = s.findAllcategory();
session.setAttribute("scs", Categorys);
}
<td>所属分类</td>
    <td>
    <select name="categoryId">
    <c:forEach items="${sessionScope.scs}" var="c">
    <option value="${c.id}">${c.name}</option>
    </c:forEach>
    </select>
    </td>
    3.整个页面采用静态包含方式做的,头在另一jsp中,定义需要的标签,通过静态包含进来
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ include file="/manager/header.jsp" %>
header.jsp页面:是所有后台jsp页面的头部
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<h1>后台管理</h1><br>
  <a href="${pageContext.request.contextPath}/manager/addCategory.jsp">添加分类</a>
  <a href="${pageContext.request.contextPath}/servlet/ManageServlet?op=showAllcategory">查看分类</a>
  <a href="${pageContext.request.contextPath}/manager/addBookjsp">添加书籍</a>
  <a href="${pageContext.request.contextPath}/servlet/ManageServlet?op=showBooks">查看书籍</a>
  <a href="#">待处理订单</a>
  <a href="#">已处理订单</a>

4.文件上传,注意过滤文件类型
4.遍历书-------》通过servlet遍历出书,返回给listBook页面
难点:
用自定义标签根据书籍分类ID获取书籍分类名称
1.自动定类,要用静态
public class Myfunctions {
private static BusinessService service = new BusinessServiceImp();
public static String findCategoryNameById(String categoryId){
Category ca = service.findCategorybyId(categoryId);
return ca.getName();
}
2.在tld文件里定义类
<function>
   <name>findCategoryNameById</name>  //函数名称
   <function-class>com.heima.functions.Myfunctions</function-class>
   <function-signature>java.lang.String findCategoryNameById(java.lang.String)</function-signature> //类里函数的定义方法和放回值
 </function>

5.前台展示内容 -----》servlet查出书的结果,前台展示也用头中尾的方式,头有用户登录、用户注册、购物车、查看订单
1.进行默认主页:index.jsp页面:
<jsp:forward page="/servlet/ClientServlet">
    <jsp:param value="showAllBooks" name="op"/>
    </jsp:forward>
2.到servlet进行控制
1.获取传过来的页面号书籍ID
String num = request.getParameter("num");
String categoryId = request.getParameter("categoryId");
2.调用获得Page的方法,把参数传进去

age page = s.findAllPageBook(num,categoryId);
3.设置jsp页面a标签的的超链接url,把参数传给jsp页面的url里
page.setUrl("/servlet/ClientServlet?op=showCategoryBooks&categoryId="+categoryId);
4.将page放进request域里
request.setAttribute("page", page);
5.转发到index.jsp页面输出

6.购物车 
map<String,CartItem> items(书ID和购物项) 购物车 关键
购物项里有:
number、price、book对象
private Book book;
private int num;//数量
//计算出价格
public float getPrice() {
return book.getPrice()*num;
}
int totalNum 总数
float totalMoney 总价
购物车里有
ef8e

Map<String,CartItem>
totalNum
toatalPrice

方法:
1.计算总数据=购物项的数量之和
public int getTotalNum() {
totalNum = 0;
for(Map.Entry<String, CartItem> entry : items.entrySet()){
totalNum += entry.getValue().getNum();
}
return totalNum;
}
2.计算总价格=购买项的价格之和
public float getToatalPrice() {
toatalPrice=0;
for(Map.Entry<String, CartItem> entry : items.entrySet()){
toatalPrice += entry.getValue().getPrice();
}
return toatalPrice;
}
3.往map添加购买项

public void addBook2Items(Book book)
if(items.containsKey(book.getId())){
//判断购物项里是否有该购物项,如果有则数量上加一
CartItem item = items.get(book.getId());
item.setNum(item.getNum()+1);
}else{
//如果没有则创建一个cartItem并添加到items中
CartItem item = new CartItem(book);
item.setNum(1);
items.put(book.getId(), item);
}
点击页面按钮购买:
到购买的servlet中控制
1.获得买书的ID
String bookId = request.getParameter("bookId");
2.查找书对象
Book book = s.findBookById(bookId);
3.创建购物车放进session域中
判断session存在的是否有购物车,如果有则用,如果没有则新建一个购物车放进session域中,保证session域中只有一个购物车
HttpSession session = request.getSession();
Cart cart = (Cart) session.getAttribute("cart");
if(cart == null){
 cart= new Cart(); 
 session.setAttribute("cart", cart);
}
4.购买的书放进购物车里
cart.addBook2Items(book);
显示购物车页面:
   <c:if test="${empty sessionScope.cart.items}">
    对不起!您没有购买任何商品
   </c:if>
   <c:if test="${!empty sessionScope.cart.items}">
    <h1>您购买的商品如下</h1>
    </c:if>
   <a href="${pageContext.request.contextPath}">继续购物</a>
 

7用户注册

1、封装用户的信息
Customer c = WebUtil.fillBean(Customer.class, request);

2.创建邮箱激活码,唯一性,并封装到bean里
String code = IdGenertor.genPK();//唯一的激活码

c.setCode(code);
3.发送邮件,用多线程发送邮件
SendMail send = new SendMail(c,request.getContextPath());
send.start();
4.调用service方法保存数据
s.regist(c);
response.getWriter().write("注册成功!我们已经发送了一封激活邮件到您的"+c.getEmail()+"邮箱中,请先激活后登陆");

    用户激活激活码:

    1.查询code和数据里的code比较,如果是则修改激活状态为true。

    Customer c = s.active(code);
if(c != null){
response.setHeader("refresh", "3;url="+request.getContextPath());
s.update(c);
response.getWriter().write("验证码成功!3秒后转向主页");
request.getSession().setAttribute("user", c);
return;
}else{
result="/error.jsp";
request.setAttribute("msg", "激活码激活失败,请重新注册账户");
}

8、生成订单
分析:书籍分类表———一对多—————》书表————一对多——————》订单项表
     用户表————一对多————》订单表————一对多————》订单项表
订单表对应购物车
订单项表对象购物项
订单表的设计:
总价格
总数量
用户Id(外键)
状态
create table orders(
id varchar(100) primary key,
ordersnum varchar(100) not null unique, //订单号
totalNum int,
status int,
totalPrice float(8,2),
customerId varchar(100),
constraint customerId_fk foreign key(customerId) references customer2(id) 
);
bean的设计:
private String id;
private int totalNum; //订单号
private float totalPrice;
private int status;//0表示未付款1已付款2未发货
private String ordersnum;
private Customer customer;  //对应表结构的customerId,在sql语句中通过customer.getId保存入orders表里
private List<OrderItem> items = new ArrayList<OrderItem>();  //在orderItem的订单项都要保存到orders订单中 orders.getItems().add(oi);

//保存订单的基本信息
run.update("insert into orders(id,ordersnum,totalNum,totalPrice,customerId,status) values(?,?,?,?,?,?)", orders.getId(),orders.getOrdersnum(),orders.getTotalNum(),orders.getTotalPrice(),orders.getCustomer().getId(),orders.getStatus());

订单项表设计:
价格
数量
bookId(外键)
订单表Id(外键)

create table ordersitem(
id varchar(100) primary key,
num int,
price float(8,2),
ordersid varchar(100),
bookid varchar(100),
constraint ordersid_fk foreign key(ordersid) references orders(id),
constraint bookid_fk foreign key(bookid) references book(id) 
);
bean的设计:
private String id;
private int num;
private float price;
private Book book;//对应表中的bookId,sql语句中book.getId取出,保存bookId到数据库里
sql语句:有订单和订单项一对多的关系,采用多条插入
Object params[][] = new Object[items.size()][];
String sql = "insert into ordersitem (id,num,price,ordersid,bookid) values(?,?,?,?,?)";
for(int i =0 ;i<items.size();i++){
OrderItem item = items.get(i);
params[i]=new Object[]{item.getId(),item.getNum(),item.getPrice(),orders.getId(),item.getBook().getId()};
}
run.batch(sql, params);

9、 在线支付
原理
1、一般用第三方支付
2、客户支付请求,选择银行。
3、按照第三规范组织数据
4、网站引导用户的浏览访问第三方支付地址
重定向Url:用get传参数

5、第三方引导用户浏览访问银行
6、支付完毕,银行引导用户浏览重定向到第三方
7、第三方引导用户访问网站的瑁
8、第三方返回信息
准备:
page.jsp页面有订单号和价格和选择的银行
配置merchantInfo.properties文件 有p1_MerId(商户编号)、keyValue(秘钥)、responseURL
在导入PaymentUtil、PropertyUtiljava工具类 定义提交银行的参数、获取properties的方法封装
步骤:1、支付后保存订单,重定向到page.jsp页面支付费用展示,提交到servlet组织参数提交给第三方支付平台
     2、在servlet把数据组织起来
      组织参数
      String ordersnum = request.getParameter("ordersnum");
String money = request.getParameter("money");
String pd_FrpId = request.getParameter("pd_FrpId");//银行
String p0_Cmd = "Buy";
String p1_MerId = PropertyUtil.getKey("p1_MerId");
String p2_Order = ordersnum;等
参数放到rquest域中:用表单控制提交
request.setAttribute("p0_Cmd",p0_Cmd );
request.setAttribute("p1_MerId",p1_MerId );
request.setAttribute("p2_Order",p2_Order );
request.setAttribute("p3_Amt",p3_Amt );
request.setAttribute("p4_Cur",p4_Cur );等
request.getRequestDispatcher("/client/sure.jsp").forward(request, response);

     3.sure.jsp采用表单控制
      <form id="f1" action="https://www.yeepay.com/app-merchant-proxy/node" method="post">
    <input type="hidden" name="p0_Cmd" value="${p0_Cmd}">
    <input type="hidden" name="p1_MerId" value="${p1_MerId}">
    <input type="hidden" name="p2_Order" value="${p2_Order}">
    <input type="hidden" name="p3_Amt" value="${p3_Amt}">
    <input type="hidden" name="p4_Cur" value="${p4_Cur}">
    <input type="hidden" name="p5_Pid" value="${p5_Pid}">
    <input type="hidden" name="p6_Pcat" value="${p6_Pcat}">
    <input type="hidden" name="p7_Pdesc" value="${p7_Pdesc}">
    <input type="hidden" name="p8_Url" value="${p8_Url}">
    <input type="hidden" name="p9_SAF" value="${p9_SAF}">
    <input type="hidden" name="pa_MP" value="${pa_MP}">
    <input type="hidden" name="pd_FrpId" value="${pd_FrpId}">
    <input type="hidden" name="pr_NeedResponse" value="${pr_NeedResponse}">
    <input type="hidden" name="hmac" value="${hmac}">
   </form>
   <script type="text/javascript">
    document.getElementById("f1").submit();
   </script>
      4.处理付款结果 付款后第三方回传递参数回来再serlvet接收,修改订单状态为已付款,在merchantInfo.properties的responseURL就是付款后返回的参数给哪一个 responseURL=http://localhost:8080/Day_Shopping/servlet/PaySuccesServlet
      public 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");  等 
}
修改订单状态未做,验证信息正确。
Boolean b= PaymentUtil.verifyCallback()方法,方法的最后一个参数是properites里设置的秘钥keyValue
数据没有问题:
//更改订单状态,注意重复提交
if("1".equals(r1_Code)){
s.changStatus(r6_Order);//根据返回的订单号修改状态
response.setHeader("refresh", "2;url="+request.getContextPath());
response.getWriter().write("支付成功,2秒后跳到主页");
}if("2".equals(r9_BType)){
response.getWriter().write("success");
}
数据有错误打印:
response.getWriter().write("数据被篡改");
修改订单状态:
用订单Dao根据订单号ID查出订单
Orders os = ors.findOrderByNum(r6_Order);
修改订单bean的status属性设为1
os.setStatus(1);
用订单Dao保存订单bean

ors.updateOrdres(os);

10、:查询用户订单
根据用户的ID查用户订单
1、判断用户是否登录,如果没有登录提示用登录
2.登录用户在session中得出用户
Customer cu= (Customer) session.getAttribute("user");
   
List<Orders> orders = s.findOrdersByCustomrId(cu.getId());   
3.把数据转给jsp页面
<th>订单号</th>
<th>数量</th>
<th>金额</th>
<th>状态</th>
<th>操作</th>
判断状态情况:如果为付款则付款,转到page.jsp付款页面,付款页面要的参数:订单号和付款金额
<td nowrap="nowrap">${o.status==0?'未付款':(o.status==1?'已付款':'已发货')}
<c:if test="${o.status==0 }">
<c:url var="u" value="/client/pay.jsp">
<c:param name="ordersnum" value="${o.ordersnum}"></c:param>
<c:param name="money" value="${o.totalPrice}"></c:param>
</c:url>
<a href="${u}">付款</a>
</c:if>
</td>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  在线支付 购物车