網上商城專案總結
經過三週的學習,網上商城專案的所有功能在今天都全部完成了,寫這個專案我學到了不少新的知識,為了以後方便回顧,把這個專案實現的功能都寫在這裡,專案是jsp+servlet+javabean實現的。
一,商城後臺
1.登入,
獲取到前臺頁面輸入的管理員使用者名稱和密碼,到資料庫進行查詢,dao層對資料庫操作,用到了QueryRunner類,建立物件時,以c3p0連線池為引數QueryRunner runner=new QueryRunner(DataSourceUtils.getDataSource());對資料庫查詢時,用runner的query(sql,ResultSetHandler,Object...params
2.分類管理,
這個模組實現了對商場所賣商品的所有類別的增刪改查,和分頁查詢,因為後續很多模組也需要用到分頁查詢,於是我們就通過反射來進行了提取,建立了PageUtil類,裡面有4個屬性private int pageSize;每頁顯示條數,private int nowPage;當前頁碼號,private int maxPage;最大頁碼號,private int totalCount;資料總條數,生成他們的get,set方法,主要程式碼為
public List<T> getList(Class name,String sql,int nowpage,int pagesize) {
QueryRunner query=new QueryRunner(DataSourceUtils.getDataSource());
try {
return query.query(sql, new BeanListHandler<T>(name), (nowpage-1)*pagesize,pagesize);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public int getMaxPage(String sql,int pagesize) {
int count=0;
QueryRunner query=new QueryRunner(DataSourceUtils.getDataSource());
try {
count=((Long)query.query(sql, new ScalarHandler())).intValue();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.totalCount=count;
int max=(count%pagesize)==0?count/pagesize:(count/pagesize)+1;
this.maxPage=max;
return maxPage;
}
只需要呼叫者兩個方法,傳入相應的引數即可得到分頁所顯示的資料,
3.商品管理
這裡主要是對商品的增刪改查操作,新增商品時,因為要顯示所有的商品類別,所以採用自定函式標籤來實現這一功能,在WEB-INF下新建資料夾,在資料夾裡新建一個.tld結尾的檔案,可根據standard.jar包下的META-INF/fn.tld裡面的內容來編寫自定義函式,寫完後如下
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>JSTL 1.1 functions library</description>
<display-name>JSTL functions</display-name>
<tlib-version>1.1</tlib-version>
<short-name>myfn</short-name>
<uri>http://lsk.com</uri>//引入自定義函式地址
<function>
<description>
select all category
</description>
<name>findAllCategories</name>//自定義方法名
<function-class>com.yinhe.dao.CategoryDao</function-class>//類的路徑
<function-signature>java.util.List findAllCategories()</function-signature>//返回型別 和類所呼叫的方法
</function>
</taglib>
前臺呼叫${myfn:findAllCategories() },這裡需要注意的是CategoryDao類中的findAllCategories方法必須為static的,不然前臺呼叫會報錯。商品圖片上傳,用到了兩個jar包commons-fileupload-1.2.1.jar 和commons-io-1.4.jar,主要實現程式碼為
//建立檔案專案工廠
DiskFileItemFactory factory=new DiskFileItemFactory();
//建立一個檔案上傳解析器
ServletFileUpload upload=new ServletFileUpload(factory);
//判斷表單enctype為否為mutipart-data
if(upload.isMultipartContent(request)){
//解析request物件,並把表單中的每一個輸入項包裝成一個fileItem 物件,並返回一個儲存了所有FileItem的list集合。
List<FileItem> list=upload.parseRequest(request);
for (FileItem fileItem : list) {
if (fileItem.isFormField()) {//普通表單處理
map.put(fileItem.getFieldName(), fileItem.getString("UTF-8"));
}else {
//檔案上傳
if (fileItem.getSize()>0) {
String fileName=fileItem.getName();
InputStream is=fileItem.getInputStream();
FileOutputStream out=new FileOutputStream(new File(path, fileName));
IOUtils.copy(is, out);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(out);
fileItem.delete();
}
}
}
商品編輯,對商品資訊進行修改,用到了回顯,修改時要判斷是否上傳了新的商品圖片,如果是則把新圖片上傳到伺服器,並修改各個欄位,然後把原來的圖片刪除了,如果否,不用進行圖片的上傳,直接修改其他欄位即可。
3.訂單管理
這裡是顯示使用者所購買過的訂單,所以只要顯示出來即可,不需要進行修改,同時也要把每個訂單下的商品通過點選訂單詳情彈出一個彈出框,將商品資訊顯示在彈出框裡,這樣就需要我們進行手動的對資料進行封裝,每個訂單含有一個訂單子項集合,每個訂單集合中又有商品物件等資訊,所以就需要對查出來的資料進行兩層封裝,
public List<Orders> getOrders(int nowpage,int pagesize) throws SQLException{
String sql="select * from orders limit ?,?";
QueryRunner qr=new QueryRunner(DataSourceUtils.getDataSource());
List<Orders> orders=qr.query(sql, new BeanListHandler<Orders>(Orders.class),(nowpage-1)*pagesize,pagesize);
for (Orders orders2 : orders) {
String sql2="select * from orderitem where oid=?";
List<Orderitem> orderitems=qr.query(sql2, new BeanListHandler<Orderitem>(Orderitem.class),orders2.getOid());
orders2.setItems((ArrayList)orderitems);
for (Orderitem orderitem : orderitems) {
String sql3="select * from product where pid=?";
Product p=qr.query(sql3, new BeanHandler<Product>(Product.class),orderitem.getPid());
orderitem.setProduct(p);
}
}
return orders;
}
前臺顯示遍歷集合,建立當前所有訂單的彈出框並隱藏,以每個訂單號給彈出框及按鈕定義類和id,點選按鈕呼叫外掛定義的方法,通過不同訂單號,來顯示當前點選訂單下的訂單詳情。
<script type="text/javascript">
$(function(){
//彈出層外掛呼叫
<c:forEach items="${list }" var="order" varStatus="vs">
new PopupLayer({
trigger:".clickedElement_${order.oid }",
popupBlk:"#showDiv_${order.oid }",
closeBtn:"#closeBtn_${order.oid }",
useOverlay:true
});
</c:forEach>
});
</script>
BaseServlet的抽取,如果一個請求對應一個servlet類那麼一個網站將會有成百上千個請求,也將對應這些類,於是我們就用到了BaseServlet的抽取,原理是反射,每個servlet類繼承BaseServlet類,請求後加入引數method和值,就會自動找到該類中的方法進行處理
package com.yinhe.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1)
throws ServletException, IOException {
arg0.setCharacterEncoding("UTF-8");
arg1.setCharacterEncoding("UTF-8");
String method=arg0.getParameter("method");
Class clazz=this.getClass();
try {
Method m=clazz.getMethod(method, HttpServletRequest.class,HttpServletResponse.class);
m.invoke(this, arg0,arg1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
二,商城前臺
1.使用者註冊
註冊頁面的表單採用了validate外掛進行了相應的驗證,同時使用者名稱也用了validate自定義方法來驗證使用者名稱是否存在,前臺通過ajax來發送請求,後臺根據使用者填寫的使用者名稱去資料庫查詢,根據查詢的結果向前臺輸出一個json型別的字串,前臺根據這個json字串來判斷使用者名稱是否存在
$.validator.addMethod("checkUN",function(){
var flag = false;
$.ajax({
url:"${pageContext.request.contextPath}/user?method=checkUser",
data:{"username":$("#username").val()},
dataType:"json",
type:"post",
//true 非同步
//false 同步
async:false,
//T2
success:function(data){
if (data=='0')
flag = true;
},error:function(e){
alert(e.responseText);
}
});
return flag;
},"使用者名稱已存在");
當用戶正確輸入所有資訊後,點選註冊,servlet處理請求,封裝user物件,由於屬性較多,我們用BeanUtils類中的populate(object, map)方法來進行封裝,需要注意的是前臺表單name值要和物件屬性名一致,封裝好後對資料庫進行插入資料然後傳送郵件
if (us.addUser(user)) {
String emailMsg = "恭喜您註冊成功,請點選下面的連線進行啟用賬戶"
+ "<a href='http://localhost:8080/Shopping/user?method=activation&&activation="+user.getCode()+"'>啟用</a>";
try {
MailUtils.sendMail(user.getEmail(), emailMsg);
response.sendRedirect("/Shopping/registerSuccess.jsp");
} catch (Exception e) {
// TODO Auto-generated catch block
response.sendRedirect("/Shopping/registerFail.jsp");
}
//response.sendRedirect("/Shopping/login.jsp");
}
這時會向用戶所填的郵箱了傳送啟用郵件,使用者點選郵箱中的啟用連結即可啟用,在資料庫中state欄位來判斷使用者是否啟用,不啟用則不能登入,實現郵箱驗證需要傳送者郵箱開通SMTP協議,還要用到工具類MailUtils.java和jar包mail.jar
package com.yinhe.utils;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
public class MailUtils {
public static void sendMail(String email, String emailMsg)
throws AddressException, MessagingException {
// 1.建立一個程式與郵件伺服器會話物件 Session
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "SMTP");
props.setProperty("mail.host", "smtp.163.com");
props.setProperty("mail.smtp.auth", "true");// 指定驗證為true
// 建立驗證器
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("[email protected]", "peiyifei888");
}
};
Session session = Session.getInstance(props, auth);
// 2.建立一個Message,它相當於是郵件內容
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]")); // 設定傳送者
message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 設定傳送方式與接收者
message.setSubject("使用者啟用");
// message.setText("這是一封啟用郵件,請<a href='#'>點選</a>");
message.setContent(emailMsg, "text/html;charset=utf-8");
// 3.建立 Transport用於將郵件傳送
Transport.send(message);
}
}
使用者點選連結後再對user表中state欄位值進行修改,然後跳轉到登入介面。
2.使用者登入,登出
就是獲取使用者從前臺輸入的使用者名稱和密碼,對user表進行查詢,如果資訊存在則將user物件存到session中,跳轉到首頁,這裡有個功能是自動登入,如果使用者點過自動登入後,關閉瀏覽器下次再開啟此網站就不用再登入了,這個功能使用了過濾器,首先判斷使用者是否選擇了自動登入,如果是就將使用者名稱和密碼存到cookie中,
String uname=request.getParameter("username");
String psw=request.getParameter("password");
String auto=request.getParameter("auto");
if ("on".equals(auto)) {
Cookie cookie=new Cookie("uname", uname);
Cookie cookie2=new Cookie("psw", psw);
cookie.setMaxAge(60*60);
cookie2.setMaxAge(60*60);
response.addCookie(cookie2);
response.addCookie(cookie);
}
User u=us.login(uname,psw);
if (u!=null) {
request.getSession().setAttribute("user", u);
response.sendRedirect("index.jsp");
}else {
request.setAttribute("message", "使用者名稱或密碼錯誤");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
建立過濾器AutoLogin.java,然後在web.xml配置 表示每個請求都要來到這個過濾器處理
<filter>
<filter-name>auto</filter-name>
<filter-class>com.yinhe.fiter.AutoLogin</filter-class>
</filter>
<filter-mapping>
<filter-name>auto</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
package com.yinhe.fiter;
import java.io.IOException;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.yinhe.bean.User;
import com.yinhe.service.UserService;
import com.yinhe.web.servlet.UserServlet;
public class AutoLogin implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request=(HttpServletRequest) arg0;
HttpServletResponse response=(HttpServletResponse)arg1;
if (request.getSession().getAttribute("user")==null) {
Cookie cookie[]=request.getCookies();
if (cookie!=null) {
String uname="";
String psw="";
for (Cookie cookie2 : cookie) {
if (cookie2.getName().equals("uname")) {
uname=cookie2.getValue();
}
if (cookie2.getName().equals("psw")) {
psw=cookie2.getValue();
}
}
UserService us=new UserService();
User user=us.login(uname, psw);
request.getSession().setAttribute("user", user);
}
}
arg2.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
在過濾器中遍歷cookie,如果找到登入時儲存的cookie則進行自動登入。
登出就是將我們儲存在session中的user和儲存在cookie中的使用者名稱和密碼進行刪除
Cookie[] cookies = request.getCookies();
if (cookies != null){
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username") || cookie.getName().equals("password")){
//刪除cookie
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
request.getSession().removeAttribute("user");
3.主頁資訊
主頁主要資訊有商品分類標題,最熱商品和最新商品,我們要把它們從資料庫中查詢出來,首先是商品分類標題,因為這個是不經常改變的,所以我們用redis伺服器來將這些資訊儲存在快取中,這樣不用每次重新整理頁面都去資料庫中查詢,同時首次查詢也採用了ajax傳送請求來進行查詢,後臺將查詢到的List<Category>集合轉換成json字串,因為手動將集合轉為json字串比較複雜,所以我們用Gson類中的toJson方法來進行轉換,使用前需要先匯入jar包gson-2.2.4.jar,也可以使用JSONArray.fromObject(list).toString()方法轉換,前提也需要匯入jar包json-lib-2.4-jdk15.jar,當管理員修改這些標題後,我們要重新查詢和儲存,所以我們用儲存在application域中的flag進行判斷,預設值為0,修改後則為1
Jedis jedis=JedisPoolUtils.getJedis();
String json_list ="";
if (jedis.get("json_list")==null||"1".equals(request.getServletContext().getAttribute("flag"))) {
request.getServletContext().setAttribute("flag", "0");
List<Category> list=cs.findAllCategories();
request.setAttribute("list", list);
//json格式轉換
Gson gson = new Gson();
json_list = gson.toJson(list);
System.out.println("資料庫查詢");
jedis.set("json_list", json_list);
}else {
json_list=jedis.get("json_list");
}
response.getWriter().println(json_list);
}
最熱商品和最新商品根據資料庫中的is_hot和pdate欄位進行查詢即可。
4.分類列表商品展示
使用者點選商品分類標籤後,傳送請求,根據標籤id來進行顯示此分類下的商品,此頁面也有分頁查詢,原理都一樣,在此不再過多介紹,
5.商品詳情展示
根據商品id查詢資料庫,然後在前臺顯示。
6.瀏覽記錄
將點選過商品的id以!連結成字串儲存在cookie中,儲存的時候要判斷是不是第一次點選該商品,如果是就將該商品id新增到字串首位,否則就移除原來的pid,再將pid新增到首位,顯示的時候,找到儲存在cookie中的字串,以!分割成陣列,遍歷陣列進行查詢,將這些商品儲存在list集合中,供前臺使用
儲存商品id
//瀏覽記錄
String pids=pid;
Cookie[] cookies=request.getCookies();
if (cookies!=null) {
for (Cookie cookie : cookies) {
if ("pids".equals(cookie.getName())) {//尋找儲存name為pid的cookie
//以!分割字串為陣列
String[] pidStrings=cookie.getValue().split("!");
//將字串轉化為LinkedList
List<String> list=Arrays.asList(pidStrings);
LinkedList<String> pidList=new LinkedList<String>(list);
//如果不是第一次點選
if (pidList.contains(pid)) {
//移除原來的,把這次放在首位
pidList.remove(pid);
pidList.addFirst(pid);
}else {
pidList.addFirst(pid);
}
if (pidList.size()>5) {
pidList.subList(5, pidList.size()).clear();
}
pids=StringUtils.join(pidList,"!");
}
}
}
Cookie cookie=new Cookie("pids", pids);
response.addCookie(cookie);
顯示瀏覽記錄
List<Product> list2=new ArrayList<Product>();
Cookie[] cookies=request.getCookies();
if (cookies!=null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("pids")) {
String pid[]=cookie.getValue().split("!");
for (String string : pid) {
Product p=ss.getProduct(string);
list2.add(p);
}
}
}
}
request.setAttribute("list2", list2);
7.購物車
由於資料庫中沒有購物車表,所以我們將購物車內的商品資訊儲存在session作用域中,為了更方便操作,我們需要對購物車進行封裝,建立cart類和cartitem類,cart類中有HashMap<String,CartItem> cartItems和總計,cartitem類種有商品物件,數量和小計。
加入購物車
String pid=request.getParameter("pid");
int buyNum=Integer.parseInt(request.getParameter("buyNum"));
Product product=ss.getProduct(pid);
Cart cart=(Cart) request.getSession().getAttribute("cart");
//如果cart為空,初始化cart
if (cart==null) {
cart=new Cart();
}
//判斷cart中有沒有當前商品
if (cart.getCartItems().containsKey(pid)) {
//如果有更新數量和小計
CartItem c=cart.getCartItems().get(pid);
c.setBuyNum(c.getBuyNum()+buyNum);
c.setSubTotal(c.getSubTotal()+product.getShop_price()*buyNum);
cart.setTotal(cart.getTotal()+product.getShop_price()*buyNum);
}else {
//如果沒有,將商品加入購物車
CartItem cartItem=new CartItem();
cartItem.setProduct(product);
cartItem.setBuyNum(buyNum);
cartItem.setSubTotal(product.getShop_price()*buyNum);
cart.getCartItems().put(pid, cartItem);
cart.setTotal(cart.getTotal()+product.getShop_price()*buyNum);
}
request.getSession().setAttribute("cart", cart);
刪除購物車內某個商品
String pid=request.getParameter("pid");
int buyNum=Integer.parseInt(request.getParameter("buyNum"));
Product product=ss.getProduct(pid);
Cart cart=(Cart) request.getSession().getAttribute("cart");
HashMap<String, CartItem> m=cart.getCartItems();
m.remove(pid);
cart.setCartItems(m);
cart.setTotal(cart.getTotal()-product.getShop_price()*buyNum);
request.getSession().setAttribute("cart", cart);
修改某個商品的數量,前臺用到了ajax,用每個商品id給數量input標籤的id賦值,用來判斷修改的是哪個商品
String pid=request.getParameter("pid");
int buyNum=1;
if (!request.getParameter("buyNum").equals("") ){
buyNum=Integer.parseInt(request.getParameter("buyNum"));
}
if (buyNum<=0) {
buyNum=1;
}
Product product=ss.getProduct(pid);
Cart cart=(Cart) request.getSession().getAttribute("cart");
HashMap<String, CartItem> m=cart.getCartItems();
CartItem item=m.get(pid);
//獲得原來的數量
int num=item.getBuyNum();
//設定新的小計
item.setSubTotal(product.getShop_price()*buyNum);
item.setBuyNum(buyNum);
m.put(pid, item);
//設定新的總價
cart.setTotal(cart.getTotal()-product.getShop_price()*num+product.getShop_price()*buyNum);
cart.setCartItems(m);
request.getSession().setAttribute("cart", cart);
//小計
double subTotal=product.getShop_price()*buyNum;
//總價
double total=cart.getTotal();
double[] d=new double[2];
d[0]=subTotal;
d[1]=total;
String jsona="";
Gson gson=new Gson();
jsona=gson.toJson(d);
response.getWriter().println(jsona);
清空購物車
從session域中清除cart即可。
8.提交訂單
點選訂單提交後,把訂單資訊存到order表中,來到提交訂單頁面,輸入收貨人,地址,電話並選擇支付銀行後點擊確認訂單,首先對資料庫order表中的資料進行修改,之後付款,這裡用到了易寶支付,匯入相應的jar包
Map<String, String[]> map=request.getParameterMap();
Orders orders=new Orders();
BeanUtils.populate(orders, map);
//更新資料庫
os.updateOrders(orders);
//跳轉到第三方支付頁面
//獲得支付所需資料
String oid=request.getParameter("oid");
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 = oid;
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);
merchantInfo.properties檔案
p1_MerId=10001126856#易寶使用者id
keyValue=cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl#祕鑰
callback=http://localhost:8080/callback#支付成功後回撥
回撥
CallbackServlet.java
package com.yinhe.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ResourceBundle;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.yinhe.service.OrderService;
import com.yinhe.utils.PaymentUtil;
public class CallbackServlet extends BaseServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(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")) {
//修改訂單狀態
OrderService orderService=new OrderService();
orderService.updateState(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("資料被篡改!");
}
}
}
支付成功後修改訂單狀態為已付款
9.我的訂單
顯示當前使用者以購買過的訂單,從資料庫查詢即可,這裡也要進行資料封裝,和後臺管理員查詢訂單原理相同。
10.登入驗證過濾器
訂單的相關操作必須進行登入才可以,如果沒登入,則自動跳轉到登入介面
自定義過濾器Login.java
package com.yinhe.fiter;
import java.io.IOException;
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 com.yinhe.bean.User;
public class Login implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse)response;
User user=(User) req.getSession().getAttribute("user");
System.out.println(user);
if (user==null) {
resp.sendRedirect("login.jsp");
}else {
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
web.xml配置,表示對訂單的相關操作必須進行登入才可以。
<filter>
<filter-name>login</filter-name>
<filter-class>com.yinhe.fiter.Login</filter-class>
</filter>
<filter-mapping>
<filter-name>login</filter-name>
<url-pattern>/ordersservlet</url-pattern>
</filter-mapping>
到此這個專案的所有功能都結束了,溫故而知新。