Java web項目綜合練習(Estore)

Java web項目綜合練習(Estorejavascript

 

 

複習day18: css

 

  1. ajax代碼的書寫步驟

 

 

2)json格式文本,轉js對象的方法是那個 html

      

 

 

  1. 項目開發流程介紹

 

這裏學習的JavaWEB項目實戰,主要是把前面學習的全部的web相關的技術綜合的練習。 前端

    

  1. 業務洽談:客戶(企業)提出需求,軟件公司派人前去洽談,第一次確認需求。
  2. 整理需求:軟件公司,不斷的和客戶進行溝通,反覆的確認需求,須要美工和前端工程師製做頁面
  3. 詳細設計:技術選型和項目原型架構
  4. 編碼階段:開工啦
  5. 測試階段:測試當前的項目,解決bug
  6. 試運行,上線。

 

在開發的流程中的人員配置: java

    洽談業務: 老闆、項目經理、技術總監、技術總監(需求工程師團隊) 程序員

    詳細設計: 項目經理、技術總監、老員工 web

    編碼: 碼農開工啦 ajax

    測試階段:測試工程師,碼農開工啦 redis

 

技術選型:選擇適合當前項目的技術 算法

項目的原型架構:導入jar包(項目須要用到哪些技術),準備配置文件,工具類,基本的接口(業務接口)

業務接口:程序員在開發的時候,當前項目須要的大部分接口,已經開發完成(技術總監),程序員只須要根據接口寫實現類

  1. 準備工做

    1. 項目搭建

      1. 新建項目

 

  1. 拷貝項目靜態資源

將文件夾中的全部數據複製到項目WebRoot文件夾下

複製完成以後,注意要修改當前項目的編碼,設置成UTF-8

 

修改完成以後,部署項目,能看到以下界面,說明拷貝靜態資源沒有問題。

搜索功能:後期使用lucence和slor這兩個技術來完成。

 

  1. 功能分析

買家功能:

  1. 註冊
  2. Ajax校驗用戶名
  3. 登陸
  4. 記住用戶名
  5. 註銷(退出)
  6. 查看商品列表
  7. 查看商品的詳細
  8. 加入購物車
  9. 查看購物車列表
  10. 修改購買的數量
  11. 刪除購物車中的商品
  12. 三級聯動
  13. 提交訂單
  14. 查看訂單列表
  15. 查看訂單詳情
  16. 在線支付(須要公網的IP,才能夠完成所有功能,只能看到支付,獲取不到支付成功的消息)
  17. 刪除訂單

 

 

賣家功能:

商品上傳

商品後臺查看

 

 

系統功能:

1. 將必定時間內沒有付款的訂單,修改成過時狀態

2. 權限控制(買家不能訪問,賣家添加商品的功能)

3. 配置錯誤頁面(404和500錯誤使用統一頁面顯示)

 

 

  1. 技術選型

技術選型:選擇實現當前這個項目,須要使用那些技術

 

前臺:jsp、JavaScript、css、EL、JSON、AJAX、html、JSTL

後臺:Servlet、JavaBean、BeanUtils、DBUtils、C3P0、MD五、JDBC、flexjson、UUID、監聽器、過濾器

數據庫:MySQL5.6

服務器:tomcat7/ tomcat6

開發工具:MyEclipse

JDK版本:1.7/1.6

J2EE版本: J2EE6.0/ J2EE5.0

操做系統:win7/win10

  1. 定義項目開發結構

定義項目開發結構:將那些java類,放到那些包中

 

 

  1. 導入項目依賴的jar包

全部jar包

導入lib文件夾:

導入後確認效果:

 

  1. 導入工具類

工具類在資料文件夾下的工具類文件夾中:

導入後的效果:

 

  1. 配置文件

配置文件在資料文件夾下的jar包文件夾中:

複製到src路徑下:

 

 

  1. 配置全站亂碼過濾器

複製資料文件夾下全站亂碼處理文件夾中(GenericEncodingFilter.java)到項目,放入cn.itcast.filter包中

 

在web.xml中配置過濾器,效果如紅框中所示:

 

 

  1. 數據庫設計

咱們在實際的開發中,不一樣的項目使用的數據庫也不一樣,一樣,咱們的estore項目,也須要設計一個數據庫

 

  1. 新建數據庫

導入資料文件夾中的數據庫腳本文件夾下的estore.sql

 

效果:

 

  1. 分析數據庫表結構

使用E-R圖分析數據庫表

矩形:實體(good商品 user用戶 order訂單)

菱形:實體和實體之間的關係

橢圓:實體中的屬性

 

 

 

  1. 導入與數據庫表對應的Java類

複製資料文件夾下的java類文件夾中的全部.java文件到:cn.itcast.domain包中

效果圖:

 

 

  1. 普通用戶功能(買家)

    1. 註冊

頁面展現:

總結:

前端js驗證:提升用戶的註冊成功率,讓用戶能一次性註冊成功(給用戶不少註冊的提示信息)。

後臺Servlet驗證:防止用戶提交非正常的數據。

  1. 功能分析

 

  1. 完善頁面(修改form表單)

  1. 修改表單提交的請求路徑
  2. 修改顯示用戶錯誤操做的提示信息

 

 

  1. Servlet實現

StringUtils.isBlank()介紹:

 

package cn.itcast.web;

 

import java.io.IOException;

import java.lang.reflect.InvocationTargetException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.beanutils.BeanUtils;

import org.apache.commons.lang3.StringUtils;

 

import cn.itcast.domain.User;

import cn.itcast.service.UserService;

import cn.itcast.service.impl.UserServiceImpl;

 

public class RegisterServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //接受請求的參數,校驗數據

        String username = request.getParameter("username");

        //非空校驗,不能==null,不能==""

        if(StringUtils.isBlank(username)){

            //表示是null或者空字符串

            request.setAttribute("msg", "用戶名不能爲空");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

        String nickname = request.getParameter("nickname");

        if(StringUtils.isBlank(nickname)|| nickname.length()>10){

            //表示是null或者空字符串

            request.setAttribute("msg", "暱稱不能爲空或者暱稱超過10個字符");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

        String password = request.getParameter("password");

        if(StringUtils.isBlank(password)){

            //表示是null或者空字符串

            request.setAttribute("msg", "密碼不能爲空");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

        String confirm_password = request.getParameter("confirm_password");

        if(StringUtils.isBlank(confirm_password)){

            //表示是null或者空字符串

            request.setAttribute("msg", "確認密碼不能爲空");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

        String captcha = request.getParameter("captcha");

        if(StringUtils.isBlank(captcha)){

            //表示是null或者空字符串

            request.setAttribute("msg", "驗證碼不能爲空");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

        //校驗兩次密碼必須一致

        if(!(password.equals(confirm_password))){

            request.setAttribute("msg", "兩次密碼必須一致");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

          

        //校驗驗證碼

        String code = (String)request.getSession().getAttribute("code");

        if(!(code.equals(captcha))){

            request.setAttribute("msg", "驗證碼錯誤");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

        //封裝數據到User對象

        User u = new User();

        try {

            BeanUtils.populate(u, request.getParameterMap());

        } catch (Exception e) {

            e.printStackTrace();

        }

        //調用service方法註冊用戶

        UserService userService = new UserServiceImpl();

        int info = userService.register(u);

          

        //根據不一樣返回值,不一樣處理

        if(info == 1){

            //註冊成功

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }else if(info == -1){

            request.setAttribute("msg", "用戶已存在");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }else{

            request.setAttribute("msg", "服務器忙,請等等,也許你打個醬油咱們就行了");

            request.getRequestDispatcher("/register.jsp").forward(request, response);

            return;

        }

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

  1. Service實現

接口:UserService

package cn.itcast.service;

 

import cn.itcast.domain.User;

 

public interface UserService {

 

    /**

     * 註冊的方法

     * @param u

     * @return

     */

    int register(User u);

}

 

 

實現類:UserServiceImpl

package cn.itcast.service.impl;

 

import cn.itcast.dao.UserDao;

import cn.itcast.dao.impl.UserDaoImpl;

import cn.itcast.domain.User;

import cn.itcast.service.UserService;

import cn.itcast.utils.MD5Utils;

 

public class UserServiceImpl implements UserService {

 

    private UserDao userDao = new UserDaoImpl();

    

    @Override

    public int register(User u) {

        // 查詢當前用戶是否存在

        int info = userDao.findByName(u.getUsername());

        if(info == 1){

            //表示,當前用戶不存在,能夠註冊

            //對用戶的密碼進行加密

            String password = MD5Utils.getPassword(u.getPassword());

            u.setPassword(password);

            //將用戶的權限設置爲user,表示普通用戶

            u.setRole("user");

            int info2 = userDao.register(u);

            return info2;

        }else{

            return info;

        }

    }

 

}

 

 

  1. DAO實現

接口:UserDao

package cn.itcast.dao;

 

import cn.itcast.domain.User;

 

public interface UserDao {

 

    /**

     * 查詢用戶名是否存在的方法

     * @param username

     * @return

     */

    int findUserByUsername(String username);

 

    /**

     * 註冊用戶的方法

     * @param u

     * @return

     */

    int register(User u);

}

 

 

實現類:UserDaoImpl

package cn.itcast.dao.impl;

 

import java.sql.SQLException;

 

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanHandler;

 

import cn.itcast.dao.UserDao;

import cn.itcast.domain.User;

import cn.itcast.utils.DBUtils;

 

public class UserDaoImpl implements UserDao {

 

    private QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

    @Override

    public int findByName(String username) {

        String sql = "select * from user where username = ?";

        try {

            User user = qr.query(sql, new BeanHandler<User>(User.class), username);

            if(user == null){

                return 1;

            }else{

                return -1;

            }

        } catch (SQLException e) {

            e.printStackTrace();

            return -2;

        }

    }

 

    @Override

    public int register(User u) {

        String sql = "insert into user values(null,?,?,?,?)";

        try {

            int update = qr.update(sql, u.getNickname(),u.getUsername(),u.getPassword(),u.getRole());

            return update;

        } catch (SQLException e) {

            e.printStackTrace();

            return -2;

        }

    }

 

}

 

  1. 使用ajax驗證用戶名是否已被註冊

提示:前端工程師書寫javascript代碼,不要去動,可是咱們本身的javascript代碼執行結果也要保留,那麼最好的解決方法,就是將結果合併。

  1. 需求分析

 

  1. 頁面實現

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

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

<c:set var="root" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>註冊</title>

<%@include file="inc/common_head.jsp"%>

<script type="text/javascript">

    //獲取ajax核心對象

    function getXHR(){

      

        var xmlhttp;

        if (window.XMLHttpRequest){

        // code for IE7+, Firefox, Chrome, Opera, Safari

            xmlhttp=new XMLHttpRequest();

        }else{

            // code for IE6, IE5

            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

        }

        return xmlhttp;

    }

    //定一個標記,用來記住本身的函數(_checkName)執行結果

    var flag = false;

    //ajax校驗用戶名

    function _checkName(_value){

        //獲取核心對象

        var xhr = getXHR();

        //使用方法發出請求

        xhr.open("get","${root}/checkName?username="+_value,true);

        xhr.send();

          

        //設置等待服務器響應

        xhr.onreadystatechange = function(){

            if(xhr.readyState == 4 && xhr.status == 200){

                //獲取響應的數據

                var data = xhr.responseText;

                var _username_notice = document.getElementById("username_notice");

                //根據返回的響應數據,不一樣處理

                if(data == 1){

                    //可使用

                    _username_notice.innerHTML = "能夠註冊";

                    _username_notice.setAttribute("style","color:green");

                    flag = true;

                }else if(data == -1){

                    //重複

                    _username_notice.innerHTML = "重複";

                    _username_notice.setAttribute("style","color:red");

                    flag = false;

                }else if(data == -3){

                    //不能爲空

                    _username_notice.innerHTML = "不能爲空";

                    _username_notice.setAttribute("style","color:red");

                    flag = false;

                }else{

                    //服務器忙

                    _username_notice.innerHTML = "服務器忙";

                    _username_notice.setAttribute("style","color:red");

                    flag = false;

                }

                //分析:當前校驗用戶名已經完成,可是,只是填寫和驗證了用戶名,尚未驗證其餘數據,可是,表單能夠提交

                //經過分析代碼,發現:在原來的表單上,onsubmit屬性,綁定了兩次函數,後一次綁定,覆蓋了前一次的效果

                //致使原來js驗證,就不起做用。

                

                //原來的js驗證須要保留,那麼,對錶單onsubmit屬性,就只能綁定一次函數,

                //定義了一個變量,記住本身的函數執行結果,而後將結果和原來的register函數的結果一塊兒運算

                //只有兩個函數結果都爲true的時候,那麼表單才能夠提交。

            }

        };

    }

</script>

 

</head>

<body>

    <%@include file="inc/header.jsp"%>

    <div class="block block1">

        <div class="blank"></div>

        <div class="usBox">

            <div class="usBox_1">

                <div class="login_tab">

                    <ul>

                        <li onclick="location.href='login.jsp';">

                            <a href="javascript:;">用戶登陸</a>

                        </li>

                        <li class="active">用戶註冊</li>

                    </ul>

                </div>

                <form id="registForm" action="${root }/register" method="post" name="formUser"

                    onsubmit="return (register() && flag);">

                    <table width="100%" border="0" align="left" cellpadding="5"

                        cellspacing="3">

                        <!-- 設置獲取用戶錯誤操做的提示信息 -->

                        <caption>${msg }</caption>

                        <tr>

                            <td width="25%" align="right">用戶名</td>

                            <td width="65%"><input name="username" type="text"

                                id="username" onblur="is_registered(this.value);_checkName(this.value);"

                                class="inputBg" /> <span id="username_notice"

                                style="color:#FF0000"> *</span></td>

                        </tr>

                        <tr>

                            <td align="right">暱稱</td>

                            <td><input name="nickname" type="text"

                                id="nickname" onblur="check_nickname(this.value);"

                                class="inputBg" /> <span id="nickname_notice"

                                style="color:#FF0000"> *</span></td>

                        </tr>

                        <tr>

                            <td align="right">密碼</td>

                            <td><input name="password" type="password" id="password1"

                                onblur="check_password(this.value);"

                                onkeyup="checkIntensity(this.value)" class="inputBg" />

                                <span style="color:#FF0000"

                                id="password_notice"> *</span></td>

                        </tr>

                        <tr>

                            <td align="right">密碼強度</td>

                            <td>

                                <table width="145" border="0" cellspacing="0" cellpadding="1">

                                    <tr align="center">

                                        <td width="33%" style="border-bottom:2px solid #ccc;" id="pwd_lower"></td>

                                        <td width="33%" style="border-bottom:2px solid #ccc;" id="pwd_middle"></td>

                                        <td width="33%" style="border-bottom:2px solid #ccc;" id="pwd_high"></td>

                                    </tr>

                                </table>

                            </td>

                        </tr>

                        <tr>

                            <td align="right">確認密碼</td>

                            <td><input name="confirm_password" type="password"

                                id="conform_password"

                                onblur="check_conform_password(this.value);" class="inputBg" />

                                <span style="color:#FF0000"

                                id="conform_password_notice"> *</span></td>

                        </tr>

                        <tr>

                            <td align="right">驗證碼</td>

                            <td><input type="text" size="8" name="captcha" id="captcha"

                                class="inputBg" onblur="check_captcha(this.value);" /> <span style="color:#FF0000"

                                id="captcha_notice"> *</span></td>

                        </tr>

                        <tr>

                            <td align="right"></td>

                            <td><img src="validatecode.jsp"

                                style="vertical-align:middle;cursor:pointer;width:130px;height:35px;margin-top:-2px;"

                                onClick="src='validatecode.jsp?'+Math.random()" /></td>

                        </tr>

                        <tr>

                            <td>&nbsp;</td>

                            <td><label> <input name="agreement" type="checkbox"

                                    value="1" checked="checked" />我已看過並接受《<a

                                    href="javascript:;" style="color:blue" target="_blank">用戶協議</a>

                            </label></td>

                        </tr>

                        <tr>

                            <td>&nbsp;</td>

                            <td align="left">

                                <input name="Submit" type="submit" value="" class="us_Submit_reg">

                            </td>

                        </tr>

                        <tr>

                            <td colspan="2">&nbsp;</td>

                        </tr>

                    </table>

                </form>

                <div class="blank"></div>

            </div>

        </div>

    </div>

    <%@include file="inc/footer.jsp"%>

</body>

</html>

 

  1. Servlet實現

package cn.itcast.web;

 

import java.io.IOException;

import java.io.PrintWriter;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.lang3.StringUtils;

 

import cn.itcast.service.UserService;

import cn.itcast.service.impl.UserServiceImpl;

 

public class CheckNameServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //校驗數據

        String username = request.getParameter("username");

        PrintWriter writer = response.getWriter();

        if(StringUtils.isBlank(username)){

            //表示數據爲空

            writer.write("-3");

            return;

        }else{

            //調用service方法

            UserService userService = new UserServiceImpl();

            int info = userService.findByName(username);

            //返回結果

            writer.write(info+"");

            return;

        }

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

}

 

 

  1. Service實現

接口: UserService

 

 

/**

     * 根據用戶名查詢的方法

     * @param username

     * @return

     */

    int findByName(String username);

 

實現類:UserServiceImpl

 

public int findByName(String username) {

        return userDao.findByName(username);

    }

  1. DAO實現

已實現,再也不重複。

  1. 登陸

在正式的開發中,使用瀏覽器測試,火狐,谷歌,IE,搜狗,360,QQ瀏覽器,測試javascript代碼

 

頁面展現;

  1. 功能分析

 

 

  1. 完善頁面

  1. 修改請求路徑
  2. 修改用戶的操做錯誤提示信息顯示位置

  1. 顯示登陸名js

<script type="text/javascript">

    window.onload = function(){

          

        var data = "${cookie.username.value}";

        var username = decodeURI(data);

        document.getElementById("_un").value = username;

    };

 

</script>

  1. Servlect實現

package cn.itcast.web;

 

import java.io.IOException;

import java.net.URLEncoder;

 

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.lang3.StringUtils;

 

import cn.itcast.domain.User;

import cn.itcast.service.UserService;

import cn.itcast.service.impl.UserServiceImpl;

 

public class LoginServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        //接受參數,校驗(username password

        String username = request.getParameter("username");

        if(StringUtils.isBlank(username)){

            request.setAttribute("msg", "用戶名不能爲空");

            request.getRequestDispatcher("/login.jsp").forward(request, response);

            return;

        }

        String password = request.getParameter("password");

        if(StringUtils.isBlank(password)){

            request.setAttribute("msg", "密碼不能爲空");

            request.getRequestDispatcher("/login.jsp").forward(request, response);

            return;

        }

        //調用service方法登陸用戶

        UserService userService = new UserServiceImpl();

        User loginUser = userService.login(username,password);

        //根局不一樣的返回值,不一樣處理

        if(loginUser == null){

            request.setAttribute("msg", "用戶名或者密碼錯誤");

            request.getRequestDispatcher("/login.jsp").forward(request, response);

            return;

        }else{

            //判斷用戶是否記住用戶名

            String remember = request.getParameter("remember");

            if("on".equals(remember)){

                Cookie cookie = new Cookie("username", URLEncoder.encode(username, "utf-8"));

                cookie.setMaxAge(60*60*24*7);

                cookie.setPath("/");

                response.addCookie(cookie);

            }else{

                Cookie cookie = new Cookie("username", "");

                cookie.setMaxAge(0);

                cookie.setPath("/");

                response.addCookie(cookie);

            }

              

              

            //loginUser存入session中,返回主頁

            request.getSession().setAttribute("loginUser", loginUser);

            response.sendRedirect(request.getContextPath());

              

        }

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:UserService

/**

     * 用戶登陸的方法

     * @param username

     * @param password

     * @return

     */

    User login(String username, String password);

 

 

實現類:UserServiceImpl

public User login(String username, String password) {

        //先對用戶的明文密碼加密

        String password2 = MD5Utils.getPassword(password);

        return userDao.login(username,password2);

    }

 

  1. DAO實現

接口:userDao

 

/**

     * 用戶登錄

     * @param username

     * @param pwd

     * @return

     */

    User login(String username, String pwd);

實現類:UserDaoImpl

public User login(String username, String password2) {

        String sql = "select * from user where username = ? and password = ?";

        try {

            return qr.query(sql, new BeanHandler<User>(User.class), username,password2);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("用戶登陸失敗");

        }

    }

 

  1. 首頁顯示歡迎信息

用戶登陸以後,頭部頁面顯示用戶的暱稱:

 

修改inc目錄下的head.jsp

 

 

 

 

  1. 查看商品

    1. 功能分析

頁面修改:

 

Ctrl + shift + r :用來搜索文件,根據文件名

Ctrl + shift + t :用來搜索java類,根據類名

 

  1. Servlet實現

package cn.itcast.web;

 

import java.io.IOException;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Good;

import cn.itcast.service.GoodService;

import cn.itcast.service.impl.GoodServiceImpl;

 

public class FindAllGoodsServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //調用service方法獲取數據

        GoodService goodService = new GoodServiceImpl();

        List<Good> list = goodService.findAll();

        //將數據存入request容器,返回goods.jsp

        request.setAttribute("list", list);

        request.getRequestDispatcher("/goods.jsp").forward(request, response);

          

          

        //測試的步驟:

        //第一:先查看請求是否發出

        //第二:服務器是否接收請求,參數是否正確

        //第三:是否調用servicedao

        //第四:返回的數據,是否正確(跟咱們預期是一致的)

        //第五:是否將數據返回給頁面

        //第六:頁面是否取出數據展現

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:GoodService

package cn.itcast.service;

 

import java.util.List;

 

import cn.itcast.domain.Goods;

 

public interface GoodService {

 

    /**

     * 獲取全部商品的方法

     * @return

     */

    List<Goods> findAllGoods();

 

}

 

 

 

實現類:GoodServiceImpl

 

package cn.itcast.service.impl;

 

import java.util.List;

 

import cn.itcast.dao.GoodDao;

import cn.itcast.dao.impl.GoodDaoImpl;

import cn.itcast.domain.Goods;

import cn.itcast.service.GoodService;

 

public class GoodServiceImpl implements GoodService {

 

    private GoodDao goodDao = new GoodDaoImpl();

    

    @Override

    public List<Goods> findAllGoods() {

        return goodDao.findAllGoods();

    }

 

}

 

 

  1. DAO實現

接口:GoodDao

 

package cn.itcast.dao;

 

import java.util.List;

 

import cn.itcast.domain.Goods;

 

public interface GoodDao {

 

    /**

     * 獲取全部商品的方法

     * @return

     */

    List<Goods> findAllGoods();

 

}

 

 

實現類:GoodDaoImpl

package cn.itcast.dao.impl;

 

import java.sql.SQLException;

import java.util.List;

 

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanListHandler;

 

import cn.itcast.dao.GoodDao;

import cn.itcast.domain.Goods;

import cn.itcast.utils.DBUtils;

 

public class GoodDaoImpl implements GoodDao {

 

    @Override

    public List<Goods> findAllGoods() {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from goods";

        try {

            return qr.query(sql, new BeanListHandler<Goods>(Goods.class));

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("獲取商品列表數據失敗");

        }

    }

 

}

 

 

 

  1. 商品列表頁面實現

  1. 有商品的狀況下遍歷循環商品列表
  2. 顯示商品圖片
  3. 顯示商品名稱
  4. 顯示市場價格和本店價格

 

 

  1. 商品詳情

    1. 功能分析

 

  1. Goods.jsp頁面完善

 

 

  1. Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Good;

import cn.itcast.service.GoodService;

import cn.itcast.service.impl.GoodServiceImpl;

 

public class FindGoodByIdServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        //獲取參數

        String parameter = request.getParameter("gid");

        //注意,這裏是有問題的

        int gid = 0;

        try {

             gid = Integer.parseInt(parameter);

        } catch (Exception e) {

            //雖然處理了異常,仍是要知道具體的異常信息

            e.printStackTrace();

            response.sendRedirect(request.getContextPath());

            return;

        }

        //調用service方法獲取數據

        GoodService goodService = new GoodServiceImpl();

        Good good = goodService.findById(gid);

        //將數據轉發到頁面

        request.setAttribute("good", good);

        request.getRequestDispatcher("/goods_detail.jsp").forward(request, response);

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

 

  1. Service實現

接口:GoodService

 

/**

     * 獲取商品數據

     * @param gid

     * @return

     */

    Good findById(int gid);

 

實現類:GoodServiceImpl

 

public Good findById(int gid) {

        return goodDao.findById(gid);

    }

 

  1. DAO實現

接口:GoodDao

 

/**

     * 獲取商品數據

     * @param gid

     * @return

     */

    Good findById(int gid);

 

實現類:GoodDaoImpl

 

public Good findById(int gid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from goods where id = ?";

        try {

            return qr.query(sql, new BeanHandler<Good>(Good.class),gid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("獲取商品詳細失敗");

        }

    }

 

  1. 頁面實現

  1. 修改大圖鏈接
  2. 圖片資源路徑
  3. 修改小圖列表資源路徑
  4. 顯示商品名稱
  5. 市場價格
  6. 商城價格
  7. 庫存
  8. 商品分類
  9. 商品描述

 

  1. 購物車

    1. 添加購物車

      1. 功能分析

 

 

  1. 頁面修改

1)修改添加商品到購物車的按鈕的鏈接

 

 

效果:

  1. Servlet實現

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.User;

import cn.itcast.service.CartService;

import cn.itcast.service.impl.CartServiceImpl;

 

public class AddGoodTOCartServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            //================跳轉以前頁面修改======================

            //記住之前的地址

            String header = request.getHeader("Referer");

            //http://localhost:8080/estore

            String str = "http://localhost:8080/estore";

            header = header.substring(str.length());

            request.getSession().setAttribute("url", header);

            //================跳轉以前頁面修改======================

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

        //獲取參數(uid gid

        String parameter = request.getParameter("gid");

        Integer gid = null;

        try {

            gid = Integer.parseInt(parameter);

        } catch (Exception e) {

            e.printStackTrace();

            response.sendRedirect(request.getContextPath());

            return;

        }

        int uid = loginUser.getId();

        //調用service方法添加商品到購物車

        CartService cartService = new CartServiceImpl();

        cartService.addGoodTOCart(uid ,gid);

        //跳轉buyorcart.jsp,讓用戶本身選擇繼續購物或者付款

        response.sendRedirect(request.getContextPath()+"/buyorcart.jsp");

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:CartService

 

/**

     * 添加商品到購物車

     * @param gid

     * @param uid

     */

    void addGoodToCart(int gid, int uid);

 

實現類:CartServiceImpl

 

private CartDao cartDao = new CartDaoImpl();

    

    @Override

    public void addGoodToCart(int gid, int uid) {

        // 查詢是否購買過

        Cart cart = cartDao.findByGidAndUid(gid,uid);

        if(cart == null){

            //沒買過,添加新的

            Cart c = new Cart();

            c.setBuynum(1);

            c.setGid(gid);

            c.setUid(uid);

            cartDao.add(c);

        }else{

            //買過了,修改數量加一

            int buynum = cart.getBuynum();

            buynum = buynum + 1;

            cart.setBuynum(buynum);

            cartDao.update(cart);

        }

    }

 

  1. DAO實現

 

接口:CartDao

 

/**

     * 根據用戶id和商品id查詢數據的方法

     * @param gid

     * @param uid

     * @return

     */

    Cart findByGidAndUid(int gid, int uid);

 

    /**

     * 添加購物車數據

     * @param c

     */

    void add(Cart c);

 

    /**

     * 修改購物車數據

     * @param cart

     */

    void update(Cart cart);

 

實現類:CartDaoImpl

 

public Cart findByGidAndUid(int gid, int uid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from cart where uid = ? and gid = ?";

         try {

            return qr.query(sql, new BeanHandler<Cart>(Cart.class), uid,gid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("獲取指定的用戶和商品的購物車數據失敗");

        }

    }

 

    @Override

    public void add(Cart c) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "insert into cart values(?,?,?)";

         try {

            qr.update(sql, c.getUid(),c.getGid(),c.getBuynum());

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("添加購物車數據失敗");

        }

    }

 

    @Override

    public void update(Cart cart) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "update cart set buynum = ? where uid = ? and gid = ?";

         try {

            qr.update(sql, cart.getBuynum(),cart.getUid(),cart.getGid());

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("添加購物車數據失敗");

        }

    }

 

 

  1. 修改buyorcart.jsp頁面連接

1)完善繼續購物和去購物車結算的連接

 

 

 

補充:登錄完成以後,直接跳轉以前瀏覽的頁面

 

  1. AddGoodToCartServlet獲取當前商品詳細頁面的路徑——查詢商品詳情的路徑,經過請求頭:Referer 獲取

  1. 將商品詳情的路徑保存,保存到session中,爲了保證後期也可使用
  2. loginServlet先獲取session中的商品詳情的路徑,判斷是否存在,存在,跳轉商品詳情的路徑,不存在,跳轉首頁

 

  1. 查看購物車

    1. 功能分析

 

  1. 在購物車對象中添加商品對象

1)修改購物車類,添加一個商品對象作屬性,方便在購物車頁面中,顯示商品信息

 

 

注意:還要生成getter和setter方法,從新生成toString方法

  1. Servlet實現

package cn.itcast.web;

 

import java.io.IOException;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Cart;

import cn.itcast.domain.User;

import cn.itcast.service.CartService;

import cn.itcast.service.impl.CartServiceImpl;

 

public class FindAllCartServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //校驗登錄

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

        //獲取數據

        int uid = loginUser.getId();

        //調用service

        CartService cartService = new CartServiceImpl();

        List<Cart> list = cartService.findAllCart(uid);

          

        //返回數據

        request.setAttribute("list", list);

        request.getRequestDispatcher("/cart.jsp").forward(request, response);

      

          

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

 

  1. Service實現

接口: CartService

 

/**

     * 查詢當前用戶購物車商品數據的方法

     * @param uid

     * @return

     */

    List<Cart> findAllCart(int uid);

 

實現類; CartServiceImpl

 

private GoodDao goodDao = new GoodDaoImpl();

    @Override

    public List<Cart> findAllCart(int uid) {

        //第一步:獲取全部的購物車數據cart

        List<Cart> list = cartDao.findAllCart(uid);

        //第二步:獲取購物車相對應商品信息

        for (Cart cart : list) {

              

            Good good = goodDao.findById(cart.getGid());

            cart.setGood(good);

        }

          

        return list;

    }

 

  1. DAO實現

接口:CartDao

 

/**

     * 查詢當前用戶購物車商品數據的方法

     * @param uid

     * @return

     */

    List<Cart> findAllCart(int uid);

 

實現類:CartDaoImpl

 

public List<Cart> findAllCart(int uid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from cart where uid = ?";

         try {

            return qr.query(sql, new BeanListHandler<Cart>(Cart.class), uid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("獲取指定的用戶的購物車數據失敗");

        }

    }

 

 

 

  1. 頁面實現

1)遍歷循環購物車集合顯示購物車中的商品信息

2)計算購物車中商品的總計

3)計算購物車中商品一共節省的金額

 

 

 

額外補充:大數據相關概念

 

  1. 修改購物車中商品的購買數量

    1. 功能分析

 

 

  1. 頁面實現

  1. 設置onblur事件,啓動js函數,函數中的參數購買數量和商品id

 

2)在js函數中,先驗證當前用戶輸入的數據,是不是數字(使用parseInt()方法,若是是整數返回true),且大於等於1

  1. 數據驗證完成以後,發送修改數量的請求,請求參數有購買的數量和商品的id

 

代碼:

<script type="text/javascript">

    function _updateBuynum(buynum,gid){

        //判斷當前用戶輸入的內容,這個內容,必須是數字,是正整數

        //是否是數字

        if(parseInt(buynum)){

            //是否是正數    

            if(buynum > 0){

                //發送請求

                location.href='${root }/updateBuynum?gid='+gid+'&buynum='+buynum;

            }else{

                alert("數字不合法");

            }

        }else{

          

            alert("數字不合法");

        }

        

    }

 

</script>

 

 

  1. Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Cart;

import cn.itcast.domain.User;

import cn.itcast.service.CartService;

import cn.itcast.service.impl.CartServiceImpl;

 

public class UpdateBuynumServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //校驗登錄

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

        //接受參數

        String parameter = request.getParameter("gid");

        String parameter2 = request.getParameter("buynum");

        int gid = 0;

        int buynum = 0;

        try {

            gid = Integer.parseInt(parameter);

            buynum = Integer.parseInt(parameter2);

        } catch (Exception e) {

            e.printStackTrace();

            response.sendRedirect(request.getContextPath());

            return;

        }

        int uid = loginUser.getId();

        Cart c = new Cart();

        c.setBuynum(buynum);

        c.setGid(gid);

        c.setUid(uid);

        //調用service方法

        CartService cartService = new CartServiceImpl();

        cartService.updateBuynum(c);

          

        //從新獲取全部的購物車數據,findAllCartServlet

        response.sendRedirect(request.getContextPath()+"/findAllCart");

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

Service接口:

/**

     * 修改數量的方法

     * @param c

     */

    void updateBuynum(Cart c);

 

實現類:

public void updateBuynum(Cart c) {

          

        cartDao.update(c);

    }

 

注意: dao已經實現過了,再也不重複

 

  1. 刪除購物車中的商品

    1. 功能分析

  1. 頁面實現

完善刪除連接,發送要被刪除的商品的gid

 

  1. Servlet實現

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.User;

import cn.itcast.service.CartService;

import cn.itcast.service.impl.CartServiceImpl;

 

public class DeleteCartServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

          

        //獲取參數(gid uid

        String parameter = request.getParameter("gid");

        int gid = 0;

        try {

            gid = Integer.parseInt(parameter);

        } catch (Exception e) {

            e.printStackTrace();

            response.sendRedirect(request.getContextPath());

            return;

        }

        int uid= loginUser.getId();

        //調用service方法,刪除數據

        CartService cartService = new CartServiceImpl();

        cartService.delete(uid , gid);

        //從新獲取全部的購物車信息

        response.sendRedirect(request.getContextPath()+"/findAllCart");

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:CartService

 

/**

     * 刪除購物車商品

     * @param uid

     * @param gid

     */

    void delete(int uid, int gid);

 

實現類:CartServiceImpl

 

public void delete(int uid, int gid) {

          

        cartDao.delete(uid,gid);

    }

 

  1. DAO實現

 

接口:CartDao

 

/**

     * 刪除購物車商品

     * @param uid

     * @param gid

     */

    void delete(int uid, int gid);

 

 

實現類:CartDaoImpl

 

public void delete(int uid, int gid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "delete from cart where uid = ? and gid = ?";

        try {

            qr.update(sql, uid,gid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("刪除購物車失敗");

        }

        

    }

 

Nosql數據庫:redis:緩存 mongdb :存儲大量文本 ,資金流

 

提示:若是購物車數據,存在session中,如何經過測試確認?換瀏覽器,查看購物車數據是否不一致。

若是購物車數據,存在數據庫中,若是如何測試確認?每次登陸購物車中數據都不會變化。

購物車存數據庫,第一:佔用空間,第二,大量的增刪改查操做,不斷與數據庫交互,性能慢

 

若是購物車數據,存在緩存中,若是如何測試確認?在服務器維護以後,購物車數據消失,就存在緩存中。

緩存:在內存中開闢的空間,存取數據的。

 

備份服務器:平時運行的服務器A,在A停機維護的時候,B服務器對外提供服務。

 

  1. 訂單

    1. 提交訂單(重點、難點)

  1. 頁面顯示購物車商品清單

1)修改查看購物車列表的servlet,將數據保存到session,方便在同一個會話中使用,在訂單頁面再次展現購物車數據不須要再從數據庫中獲取

 

 

  1. 在訂單的提交頁面顯示用戶要購買的商品數據

     

    遍歷商品集合,計算商品的總價

 

 

 

  1. Ajax實現省市縣三級聯動

功能分析:

第一步:頁面加載完成以後,顯示省一級地區的數據

第二步:選擇省的時候,加載相對應的市的數據

第三步:選擇市的時候,加載相對應的縣的數據

 

流程圖:

 

  1. Ajax代碼

<script type="text/javascript">

        //獲取核心對象的方法

        function getXHR(){

            var xmlhttp;

            if (window.XMLHttpRequest){

                // code for IE7+, Firefox, Chrome, Opera, Safari

                xmlhttp=new XMLHttpRequest();

            }else{

                // code for IE6, IE5

                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

            }

            return xmlhttp;

        }

 

        //書寫ajax代碼步驟:

        //第一步:獲取核心對象

        //第二步:發送請求open方法 send方法

        //第三步:設置等待響應

        //第四步:獲取響應數據,根據業務處理數據

          

        window.onload = function(){

            var xhr = getXHR();

              

            xhr.open("GET","${root}/getData?pid=0",true);

            xhr.send();

              

            xhr.onreadystatechange = function(){

              

                if(xhr.readyState == 4 && xhr.status == 200){

                    //data是字符串數據,將他轉換成javascript對象

                    var data = xhr.responseText;

                    //eval 這個函數是將字符串,轉換成javascript代碼,

                    //JSON.parse()出來以後,eval就開始淘汰

                    var arr = JSON.parse(data);

                    var _province = document.getElementById("province");

                    for ( var i = 0; i < arr.length; i++) {

                        //不斷建立option,添加到省一級地區的select標籤中

                        var _option = document.createElement("option");

                        _option.setAttribute("value", arr[i].id);

                        _option.innerHTML = arr[i].name;

                          

                        _province.appendChild(_option);

                    }

                }

            };        

        };

          

        function _getCity(value){

            var _city = document.getElementById("city");

            //清空數據

            _city.length = 1;

                var _district = document.getElementById("district");

            //清空數據

            _district.length = 1;

            var xhr = getXHR();

              

            xhr.open("GET","${root}/getData?pid="+value,true);

            xhr.send();

              

            xhr.onreadystatechange = function(){

              

                if(xhr.readyState == 4 && xhr.status == 200){

                    var data = xhr.responseText;

                    var arr = JSON.parse(data);

                  

                    for ( var i = 0; i < arr.length; i++) {

                        //不斷建立option,添加到省一級地區的select標籤中

                        var _option = document.createElement("option");

                        _option.setAttribute("value", arr[i].id);

                        _option.innerHTML = arr[i].name;

                          

                        _city.appendChild(_option);

                    }

                }

            };        

          

        }

        function _getDistrict(value){

            var _district = document.getElementById("district");

            //清空數據

            _district.length = 1;

            var xhr = getXHR();

              

            xhr.open("GET","${root}/getData?pid="+value,true);

            xhr.send();

              

            xhr.onreadystatechange = function(){

              

                if(xhr.readyState == 4 && xhr.status == 200){

                    var data = xhr.responseText;

                    var arr = JSON.parse(data);

                  

                    for ( var i = 0; i < arr.length; i++) {

                        //不斷建立option,添加到省一級地區的select標籤中

                        var _option = document.createElement("option");

                        _option.setAttribute("value", arr[i].id);

                        _option.innerHTML = arr[i].name;

                          

                        _district.appendChild(_option);

                    }

                }

            };        

        }

 

 

</script>

  1. Servlet代碼實現

 

package cn.itcast.web;

 

import java.io.IOException;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.PCD;

import cn.itcast.service.PCDService;

import cn.itcast.service.impl.PCDServiceImpl;

import flexjson.JSONSerializer;

 

public class GetDataServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //獲取pid

        String parameter = request.getParameter("pid");

        int pid = 0;

        try {

            pid = Integer.parseInt(parameter);

        } catch (Exception e) {

            e.printStackTrace();

            response.sendRedirect(request.getContextPath());

            return;

        }

          

        //調用service方法

        PCDService pcdService = new PCDServiceImpl();

        List<PCD> list = pcdService.getData(pid);

          

        //將數據轉換成json格式

        JSONSerializer serializer = new JSONSerializer();

        String serialize = serializer.serialize(list);

          

        //發出響應

        response.getWriter().write(serialize);

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

  1. 省市聯動Service實現

接口:ProvinceService

package cn.itcast.service;

 

import java.util.List;

 

import cn.itcast.domain.PCD;

 

public interface PCDService {

 

    /**

     * 獲取地區數據的方法

     * @param pid

     * @return

     */

    List<PCD> getData(int pid);

 

}

 

實現類:ProvinceServiceImpl

package cn.itcast.service.impl;

 

import java.util.List;

 

import cn.itcast.dao.PCDDao;

import cn.itcast.dao.impl.PCDDaoImpl;

import cn.itcast.domain.PCD;

import cn.itcast.service.PCDService;

 

public class PCDServiceImpl implements PCDService {

 

    private PCDDao pcdDao = new PCDDaoImpl();

    @Override

    public List<PCD> getData(int pid) {

        return pcdDao.getData(pid);

    }

 

}

 

 

  1. 省市聯動Dao實現

接口: ProvinceDao

package cn.itcast.dao;

 

import java.util.List;

 

import cn.itcast.domain.PCD;

 

public interface PCDDao {

 

    List<PCD> getData(int pid);

 

}

 

實現類:ProvinceDaoImpl

package cn.itcast.dao.impl;

 

import java.sql.SQLException;

import java.util.List;

 

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanListHandler;

 

import cn.itcast.dao.PCDDao;

import cn.itcast.domain.PCD;

import cn.itcast.utils.DBUtils;

 

public class PCDDaoImpl implements PCDDao {

 

    @Override

    public List<PCD> getData(int pid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from province_city_district where pid = ?";

        try {

            return qr.query(sql, new BeanListHandler<PCD>(PCD.class), pid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("獲取地區數據失敗");

        }

    }

 

}

 

 

  1. 訂單生成頁面修改

  1. 修改表單請求路徑

  1. 將被選中的省市縣數據存入隱藏域中

 

  1. 訂單生成頁面流程分析

 

 

  1. 訂單生成Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Cart;

import cn.itcast.domain.Order;

import cn.itcast.domain.OrderItems;

import cn.itcast.domain.User;

import cn.itcast.service.OrderService;

import cn.itcast.service.impl.OrderServiceImpl;

import cn.itcast.utils.UUIDUtils;

 

public class AddOrderServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

          

        //獲取和封裝數據

        //封裝訂單的數據

        String oid = UUIDUtils.getUUID();

        int uid = loginUser.getId();

        double totalprice = 0;

        //獲取session中的購物車數據,來計算總金額

        List<Cart> list = (List<Cart>)request.getSession().getAttribute("list");

        //準備一個集合,用來保存OrderItems

        List<OrderItems> oiList = new ArrayList<OrderItems>();

          

        for (Cart cart : list) {

            totalprice = totalprice + cart.getBuynum() * cart.getGood().getEstoreprice();

            //獲取全部商品的信息,將數據存入OrderItems,而後,再存入List集合

            OrderItems oi = new OrderItems();

            //訂單編號

            oi.setOid(oid);

            //商品的編號

            oi.setGid(cart.getGood().getId());

            oi.setBuynum(cart.getBuynum());

              

            oiList.add(oi);

        }

        //設置支付狀態:1 待付款

        int status = 1;

        Date createtime = new Date();

        //省市縣

        String province = request.getParameter("province");

        String city = request.getParameter("city");

        String district = request.getParameter("district");

        //詳細地址,郵編姓名電話

        String detailAddress = request.getParameter("detailAddress");

        String zipcode = request.getParameter("zipcode");

        String name = request.getParameter("name");

        String telephone = request.getParameter("telephone");

          

        String address = province +"(省/市)"+city+"(市/區)"+district+"(縣/鎮)"+

        detailAddress+"郵編:"+zipcode+"姓名:"+name+"電話:"+telephone;

          

        Order o = new Order();

        o.setAddress(address);

        o.setCreatetime(createtime);

        o.setId(oid);

        o.setStatus(status);

        o.setTotalprice(totalprice);

        o.setUid(uid);

        o.setOiList(oiList);

          

        //調用service方法添加訂單

        OrderService orderService = new OrderServiceImpl();

        orderService.add(o);

        //調用查詢所有訂單Servlet,查看效果

        response.sendRedirect(request.getContextPath()+"/orders.jsp");

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. 訂單生成Service實現

接口:OrderService

package cn.itcast.service;

 

import cn.itcast.domain.Order;

 

public interface OrderService {

 

    /**

     * 添加訂單的方法

     * @param o

     */

    void add(Order o);

 

}

 

實現類:OrderServiceImpl

package cn.itcast.service.impl;

 

import java.sql.Connection;

import java.sql.SQLException;

 

import cn.itcast.dao.CartDao;

import cn.itcast.dao.OrderDao;

import cn.itcast.dao.impl.CartDaoImpl;

import cn.itcast.dao.impl.OrderDaoImpl;

import cn.itcast.domain.Order;

import cn.itcast.service.OrderService;

import cn.itcast.utils.DBUtils;

 

public class OrderServiceImpl implements OrderService {

 

    private OrderDao orderDao = new OrderDaoImpl();

    private CartDao cartDao = new CartDaoImpl();

    @Override

    public void add(Order o) {

        //獲取數據庫鏈接

        Connection conn = null;

        try {

            conn = DBUtils.getConnection();

            //開啓事務

            conn.setAutoCommit(false);

            //添加訂單

            orderDao.add(o,conn);

            //添加訂單明細

            orderDao.addOrderItems(o.getOiList(),conn);

              

            //清空購物車

            cartDao.clear(o.getUid(),conn);

            //提交事務

            conn.commit();

            //異常回滾

              

        } catch (Exception e) {

            e.printStackTrace();

            try {

                conn.rollback();

            } catch (SQLException e1) {

                e1.printStackTrace();

            }

        }

          

 

    }

 

}

 

  1. 訂單生成DAO實現

接口:OrderDao

 

package cn.itcast.dao;

 

import java.sql.Connection;

import java.util.List;

 

import cn.itcast.domain.Order;

import cn.itcast.domain.OrderItems;

 

public interface OrderDao {

 

    /**

     * 添加訂單

     * @param o

     * @param conn

     */

    void add(Order o, Connection conn);

 

    /**

     * 添加訂單明細

     * @param oiList

     * @param conn

     */

    void addOrderItems(List<OrderItems> oiList, Connection conn);

 

}

 

 

實現類:OrderDaoImpl

 

package cn.itcast.dao.impl;

 

import java.sql.Connection;

import java.sql.SQLException;

import java.util.List;

 

import org.apache.commons.dbutils.QueryRunner;

 

import cn.itcast.dao.OrderDao;

import cn.itcast.domain.Order;

import cn.itcast.domain.OrderItems;

 

public class OrderDaoImpl implements OrderDao {

 

    @Override

    public void add(Order o, Connection conn) {

        //QueryRunner():建立一個與數據庫無關的QueryRunner對象,後期在使用增刪改查的方法的時候,手動提供一個鏈接

        QueryRunner qr = new QueryRunner();

        String sql = "insert into orders values(?,?,?,?,?,?)";

        try {

            qr.update(conn, sql, o.getId(),o.getUid(),o.getTotalprice(),o.getAddress(),o.getStatus(),o.getCreatetime());

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("添加訂單失敗");

        }

    }

 

    @Override

    public void addOrderItems(List<OrderItems> oiList, Connection conn) {

        QueryRunner qr = new QueryRunner();

        String sql = "insert into orderitems values(?,?,?)";

        for (OrderItems oi : oiList) {

            try {

                qr.update(conn, sql, oi.getOid(),oi.getGid(),oi.getBuynum());

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("添加訂單明細失敗");

            }

              

        }

    }

 

}

 

 

接口:CartDao

/**

     * 清空購物車

     * @param uid

     * @param conn

     */

    void clear(int uid, Connection conn);

 

實現類:CartDaoImpl

public void clear(int uid, Connection conn) {

        QueryRunner qr = new QueryRunner();

        String sql = "delete from cart where uid = ?";

        try {

            qr.update(conn, sql, uid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("清空購物車失敗");

        }

        

    }

 

  1. 查看訂單列表

    1. 功能分析

 

 

  1. Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Order;

import cn.itcast.domain.User;

import cn.itcast.service.OrderService;

import cn.itcast.service.impl.OrderServiceImpl;

 

public class FindAllOrdersServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

        //獲取參數

        int uid= loginUser.getId();

        //調用service方法

        OrderService orderService = new OrderServiceImpl();

        List<Order> oList = orderService.findAll(uid);

        //轉發數據到orders.jsp展現數據

        request.setAttribute("oList", oList);

        request.getRequestDispatcher("/orders.jsp").forward(request, response);

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:OrderService

 

/**

     * 查詢指定用戶的全部的訂單

     * @param uid

     * @return

     */

    List<Order> findAll(int uid);

 

實現類:OrderServiceImpl

public List<Order> findAll(int uid) {

        return orderDao.findAll(uid);

    }

  1. DAO實現

接口:OrderDao

 

/**

     * 查詢指定用戶的訂單

     * @param uid

     * @return

     */

    List<Order> findAll(int uid);

 

 

實現類: OrderDaoImpl

 

public List<Order> findAll(int uid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql= "select * from orders where uid = ?";

        try {

            return qr.query(sql, new BeanListHandler<Order>(Order.class), uid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("查詢指定的用戶訂單失敗");

        }

    }

 

  1. 頁面實現

  1. 顯示訂單相關信息
  2. 根據訂單的狀態顯示不一樣效果,status==1未支付——在線支付、取消訂單,status==2,已支付——查看詳細,status==3已過時——查看詳細

  1. 查看訂單詳情

    1. 功能分析

  1. Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Order;

import cn.itcast.domain.User;

import cn.itcast.service.OrderService;

import cn.itcast.service.impl.OrderServiceImpl;

 

public class FindOrderByIdServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

          

        //獲取參數oid

        String oid = request.getParameter("oid");

        //調用service獲取數據

        OrderService orderService = new OrderServiceImpl();

        Order o = orderService.findById(oid);

          

        //轉發數據到orders_detail.jsp

        request.setAttribute("order", o);

        request.getRequestDispatcher("/orders_detail.jsp").forward(request, response);

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:OrderService

 

/**

     * 根據訂單id獲取數據的方法

     * @param oid

     * @return

     */

    Order findById(String oid);

 

實現類:OrderServiceImpl

 

private GoodDao goodDao = new GoodDaoImpl();

    @Override

    public Order findById(String oid) {

        // 獲取訂單數據

        Order o = orderDao.findById(oid);

          

        //獲取訂單明細

        List<OrderItems> oiList = orderDao.findOrderItemsByOid(oid);

        for (OrderItems oi : oiList) {

            //獲取商品信息

            Good good = goodDao.findById(oi.getGid());

            oi.setGood(good);

        }

          

        //封裝數據返回給調用者

        o.setOiList(oiList);

        return o;

    }

 

 

  1. Dao實現

接口:OrderDao

 

/**

     * 根據id查詢訂單

     * @param oid

     * @return

     */

    Order findById(String oid);

 

    /**

     * 根據oid獲取訂單明細

     * @param oid

     * @return

     */

    List<OrderItems> findOrderItemsByOid(String oid);

 

實現類: OrderDaoImpl

 

@Override

    public Order findById(String oid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql="select * from orders where id = ?";

        try {

            return qr.query(sql,new BeanHandler<Order>(Order.class), oid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("查詢指定的訂單失敗");

        }

    }

 

    @Override

    public List<OrderItems> findOrderItemsByOid(String oid) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from orderitems where oid = ?";

        try {

            return qr.query(sql, new BeanListHandler<OrderItems>(OrderItems.class), oid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("查詢指定的訂單明細失敗");

        }

    }

 

 

  1. 頁面修改

  1. 在訂單編號上添加a標籤,連接指向訂單詳情
  2. 一樣也修改後面的訂單的查看詳情連接
  3. 顯示訂單的信息和相關的商品信息
  4. 要顯示訂單的總價

 

 

 

  1. 取消訂單

    1. 功能分析

 

  1. 編輯取消訂單的連接

1)設置取消訂單的連接

 

 

  1. Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.User;

import cn.itcast.service.OrderService;

import cn.itcast.service.impl.OrderServiceImpl;

 

public class DeleteOrderServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

          

        //獲取參數

        String oid = request.getParameter("oid");

          

        //調用service方法,刪除數據

        OrderService orderService = new OrderServiceImpl();

        orderService.delete(oid);

          

        //重定向訪問,findAllOrdersServlet

        response.sendRedirect(request.getContextPath()+"/findAllOrders");

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

  1. Service實現

接口:OrderService

 

/**

     * 刪除訂單的方法

     * @param oid

     */

    void delete(String oid);

 

實現類:

public void delete(String oid) {

          

        //獲取鏈接

        Connection conn = null;

        try {

            conn = DBUtils.getConnection();

            //開啓事務

            conn.setAutoCommit(false);

            //刪除訂單明細

            orderDao.deleteOrderItemsByOid(oid,conn);

            //刪除訂單

            orderDao.delete(oid,conn);

              

            //提交事務

            conn.commit();

            //異常回滾

              

        } catch (Exception e) {

            e.printStackTrace();

            try {

                conn.rollback();

            } catch (SQLException e1) {

                e1.printStackTrace();

            }

        }

    }

 

  1. DAO實現

接口:OrderDao

 

/**

     * 刪除訂單明細

     * @param oid

     * @param conn

     */

    void deleteOrderItemsByOid(String oid, Connection conn);

 

    /**

     * 刪除訂單

     * @param oid

     * @param conn

     */

    void delete(String oid, Connection conn);

 

 

實現類:OrderDaoImpl

 

@Override

    public void deleteOrderItemsByOid(String oid, Connection conn) {

        QueryRunner qr = new QueryRunner();

        String sql = "delete from orderitems where oid = ?";

        try {

            qr.update(conn, sql, oid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("刪除指定的訂單明細失敗");

        }

        

    }

 

    @Override

    public void delete(String oid, Connection conn) {

        QueryRunner qr = new QueryRunner();

        String sql="delete from orders where id = ?";

        try {

            qr.update(conn, sql, oid);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("刪除指定的訂單失敗");

        }

    }

 

  1. 管理員功能(賣家)

    1. 添加商品

      1. 功能分析

 

頁面修改:

  1. 修改表單請求路徑

 

 

 

  1. Servlet實現

package cn.itcast.web;

 

import java.io.File;

import java.io.IOException;

import java.lang.reflect.InvocationTargetException;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.beanutils.BeanUtils;

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.FileUploadException;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

 

import cn.itcast.domain.Good;

import cn.itcast.domain.User;

import cn.itcast.service.GoodService;

import cn.itcast.service.impl.GoodServiceImpl;

import cn.itcast.utils.DirUtils;

import cn.itcast.utils.UUIDUtils;

 

public class AddGoodServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

          

        //校驗登陸

        User loginUser = (User)request.getSession().getAttribute("loginUser");

        if(loginUser == null){

            response.sendRedirect(request.getContextPath()+"/login.jsp");

            return;

        }

          

        //保證圖片上傳成功

          

        //fileUpload技術,核心對象,DiskFileItemFactory ServletFileUpload FileItem

        //DiskFileItemFactory:輔助做用,幫助解析request,將數據解析成一個一個的FileItem

        //ServletFileUpload:解析的核心對象,須要綁定DiskFileItemFactory

        //FileItem:封裝了全部input輸入框的數據的對象

          

        DiskFileItemFactory factory = new DiskFileItemFactory();

        //DiskFileItemFactory綁定到ServletFileUpload

        ServletFileUpload fileUpload = new ServletFileUpload(factory);

        //建立一個map集合用來存儲good相關數據

        Map<String ,Object> map = new HashMap<String ,Object>();

        try {

            //解析request對象

            List<FileItem> list = fileUpload.parseRequest(request);

              

            //針對集合進行遍歷,判斷當前fileItem是不是一個普通字段,仍是文件上傳

            for (FileItem item : list) {

                //判斷當前是不是普通字段

                if(item.isFormField()){

                    //表示,我是普通字段

                    //獲取inputname

                    String fieldName = item.getFieldName();

                    //獲取inputvalue

                    String value = item.getString("utf-8");

                      

                    //將數據保存到一個map集合

                    map.put(fieldName, value);

                }else{

                    //我是文件上傳

                    //肯定upload文件夾的位置,要保存圖片在這個文件家中

                    //String realPath = this.getServletContext().getRealPath("/upload");

                    //要輸出一個文件,要獲取文件名

                    String fileName = item.getName();

                    //爲了防止重複,須要使用UUID,重寫文件名

                    String uuid = UUIDUtils.getUUID();

                    fileName = uuid + fileName;

                    //目錄打散,在upload文件路徑後,再加幾層目錄,

                    String dir = DirUtils.getDir(fileName);

                    //這個文件目錄,可能不存在,須要判斷,若是不存在,建立

                    //輸出指定位置,要在指定位置下,目錄打散

                    File file = new File("c:/picture",dir);

                    if(file.exists()){

                        //存在,什麼都不作

                    }else{

                        file.mkdirs();

                    }

                    //向指定位置輸出文件

                    try {

                        item.write(new File("c:/picture"+dir,fileName));

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                    //保存圖片上傳地址,後期才能經過路徑找到圖

                    // /upload/11/9/f913990ee3f04e029dd34f7d55a60fb1.jpg

                    // /upload/14/13/c39e4f0266b745a3b91d2697b9d6c544WIN_20151231_16_46_42_Pro.jpg

                    map.put("imgurl", "/picture"+dir+"/"+fileName);

                }

            }

              

        } catch (FileUploadException e) {

            e.printStackTrace();

        }

          

          

        //封裝數據到good對象

        Good g = new Good();

        try {

            BeanUtils.populate(g, map);

        } catch (Exception e) {

            e.printStackTrace();

        }

        //調用service方法添加商品

        GoodService goodService = new GoodServiceImpl();

        goodService.addGood(g);

          

        //查看全部商品

        response.sendRedirect(request.getContextPath()+"/goods_admin.jsp");

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

 

 

  1. Service實現

接口:GoodService

/**

     * 添加商品

     * @param g

     */

    void addGood(Good g);

 

實現類:GoodServiceImpl

 

public void addGood(Good g) {

        goodDao.addGood(g);

    }

 

  1. DAO實現

接口:GoodDao

 

/**

     * 添加商品

     * @param g

     */

    void addGood(Good g);

 

實現類:GoodDaoImpl

 

public void addGood(Good g) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "insert into goods values(null,?,?,?,?,?,?,?)";

        try {

            qr.update(sql, g.getName(), g.getMarketprice(), g.getEstoreprice(),

                    g.getCategory(), g.getNum(), g.getImgurl(),

                    g.getDescription());

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("添加商品失敗");

        }

    }

 

補充內容:

根據演示效果——從新部署服務器以後,會丟失商品圖片

 

解決方案:將圖片保存與項目和服務器無關的位置

思路:

1:保證圖片上傳的時候,必定將圖片保存到指定位置(c:/picture)

2: 保存圖片的url的時候,路徑,必定/picture/11/12/1.jpg。

3:專門設計一個Servlet,接受處理圖片請求,在Servlet中,讀取圖片資源,

使用IO技術,而後使用response對象發出響應


修改請求地址(例如,在商品列表頁面):/estore2/pic?imgurl=/picture/8/15/774595f7c5b44fefa7b08b9cc5969e9f.jpg

PictureServlet:

package cn.itcast.web;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class PictureServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        //1)瀏覽器發送請求給服務器(商品須要圖片名稱)

        // /picture/14/1/85a3510c83ef4fc98afbb4a4a0095e2e2.jpg

        String imgurl = request.getParameter("imgurl");

        //2)讀取服務器硬盤上的圖片數據

        FileInputStream in = new FileInputStream(new File("c:"+imgurl));

          

        //3)使用IO技術,將數據發送(使用response對象發送數據)

        ServletOutputStream out = response.getOutputStream();

        byte[] buf =new byte[1024];

        int len = 0;

        while((len = in.read(buf)) != -1){

            out.write(buf, 0, len);

        }

        

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

  1. 查看商品(管理員)

爲何,已經存在商品列表功能,還要在後臺製做一個商品列表給管理員?

注意:設計一個項目,分角色,角色下有權限,那麼不一樣角色有不一樣權限,

 

做爲買家,普通用戶,沒法使用管理員功能

同理,做爲管理員,沒法使用普通用戶功能,只能從新制做一個讓管理員使用。

 

 

添加完成商品後,從數據庫中從新查詢全部商品,展現在goods_admin.jsp頁面上

Servlet實現:

 

package cn.itcast.web;

 

import java.io.IOException;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.domain.Good;

import cn.itcast.service.GoodService;

import cn.itcast.service.impl.GoodServiceImpl;

 

public class QueryAllGoodsAdminServelt extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

 

        // 調用service方法獲取數據

        GoodService goodService = new GoodServiceImpl();

        List<Good> list = goodService.findAll();

        // 將數據存入request容器,返回goods.jsp

        request.setAttribute("list", list);

        request.getRequestDispatcher("/goods_admin.jsp").forward(request, response);

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

  1. 權限管理

爲何要作權限管理?

 

商品上傳,只有賣家可使用,買家是不能使用的,須要作權限的控制

 

如何實現權限管理?

 

咱們要解決,誰,是什麼角色,能作哪些操做?

 

兩種權限數據解決方案:

    

第一種:使用數據庫表,來控制用戶的權限,通常須要5張表(用戶表 角色表 權限表 用戶角色表 角色權限表)

 

5張表之間的關係:

 

    第二種:使用配置文件管理權限

在用戶表中直接設置用戶的角色,將角色的權限設置在配置文件中,後期用戶訪問的時候,將用戶的請求路徑和角色權限配置文件中的內容比較,若是一致表示用戶擁有該權限。

 

在用戶表中直接設置用戶的角色——用戶和角色都在一張表。

將角色的權限設置在配置文件中——使用一個txt文件,保存角色對應的權限

將用戶的請求路徑和角色權限配置文件中的內容比較——request獲取請求路徑,要與配置文件的中內容一致,有權限

 

    如何定義配置角色權限配置文件?

普通用戶權限,存放在user.txt

管理員權限,存在admin.txt

 

普通用戶權限user.txt:

 

管理員權限admin.txt:

第二種解決方案代碼實現:

 

使用什麼技術作權限的控制?

過濾器。

 

實現步驟:

第一步:建立兩個集合,準備加載權限的數據

第二步:在過濾器初始化的時候,加載權限的數據

第三步:獲取用戶的請求

第四步:開始比對,用戶的請求和用戶所具備的權限是否一致

第五步:一致,放行,不一致,拋出異常

 

代碼實現:

package cn.itcast.filter;

 

import java.io.BufferedReader;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.ArrayList;

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 cn.itcast.domain.User;

 

public class PrivilegeFilter implements Filter{

    //第一步:建立兩個集合,準備加載權限的數據

    //建立集合存放user的權限

    private List<String> userList = new ArrayList<String>();

    //建立集合存放admin的權限

    private List<String> adminList = new ArrayList<String>();

    

    @Override

    public void init(FilterConfig config) throws ServletException {

        System.out.println("==================權限數據開始加載==============");

        //第二步:在過濾器初始化的時候,加載權限的數據

          

        //如何肯定user.txt文件的位置。WEB-INF/classes

          

        //先獲取servletContext對象,經過他來調用getRealPath(),獲取到的是配置文件路徑

        String realPath = config.getServletContext().getRealPath("WEB-INF/classes/user.txt");

        //服務器上路徑:C:\apache-tomcat-7.0.52\webapps\estore2\WEB-INF\classes/user.txt

        // C:\apache-tomcat-7.0.52\webapps\estore2\WEB-INF\classes/user.txt

        //System.out.println(realPath);

        try {

            //能夠經過BufferedReader讀取配置文件,一行一行的讀取

            BufferedReader reader = new BufferedReader(new FileReader(new File(realPath)));

            String line = null;

            while( (line = reader.readLine()) != null){

                //將數據存入集合

                userList.add(line);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

        System.out.println(userList);

          

        String realPath2 = config.getServletContext().getRealPath("WEB-INF/classes/admin.txt");

          

        try {

            BufferedReader reader = new BufferedReader(new FileReader(new File(realPath2)));

            String line = null;

            while((line = reader.readLine()) != null){

                adminList.add(line);

            }

              

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        System.out.println(adminList);

          

        System.out.println("==================權限數據加載完成 ==============");

    }

 

    @Override

    public void doFilter(ServletRequest request, ServletResponse response,

            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest)request;

        HttpServletResponse res = (HttpServletResponse)response;

          

        //第三步:獲取用戶的請求,將請求和配置文件中權限進行比對,若是一致,放行,不一致,拋出異常

          

        //獲取用戶的請求

        String requestURI = req.getRequestURI();

        //requestURI——————/estore2/findAllGoods

        requestURI = requestURI.substring(req.getContextPath().length());

        // /findAllGoods

        System.out.println(requestURI);

          

        //有一些頁面和Servlet請求,不須要管理

        //須要知道,那些請求須要被關管理,發現,只有請求,包含在集合中,就須要被管理

        boolean isUser = userList.contains(requestURI);

        boolean isAdmin = adminList.contains(requestURI);

          

        if(isUser || isAdmin){

            //表示這個請求,是一個須要被管理的權限

            //第四步:開始比對,用戶的請求和用戶所具備的權限是否一致

              

            //獲取用戶的登陸信息loginUser role :記錄用戶的角色,這個角色對應的權限配置文件

            User loginUser = (User)req.getSession().getAttribute("loginUser");

            if(loginUser == null){

                res.sendRedirect(req.getContextPath()+"/login.jsp");

                return;

            }else{

                //能夠獲取角色,能夠進行比對

                if("user".equals(loginUser.getRole()) && isUser){

                    //"user".equals(loginUser.getRole())

                    //判斷你的角色是不是一個普通用戶

                    //isUser==true:用戶請求,是請求了一個普通用戶權限

                    //isUser==false:用戶請求,是請求了一個管理員用戶權限

                      

                    //當前用戶是一個普通用戶,並且,請求的權限是普通用戶權限

                    //放行

                    chain.doFilter(req, res);

                }else if("admin".equals(loginUser.getRole()) && isAdmin){

                    //當前用戶是一個管理員用戶,他請求的權限也是管理員權限

                    //放行

                    chain.doFilter(req, res);

                }else{

                    //表示當前用戶的角色和權限不一致

                    throw new RuntimeException("權限不足,請聯繫超級管理員!");

                }

            }

              

        }else{

            //不須要管理的權限

            chain.doFilter(req, res);

        }

    }

 

    @Override

    public void destroy() {

        

    }

 

}

 

  1. 配置網站錯誤頁面

軟件在運行時,會出現各類錯誤,這些錯誤不但願用戶看到,這時須要配置一個統一的錯誤頁面,當系統出錯時,就會跳轉到這個錯誤頁面,這個錯誤頁面通常比較友好

在web.xml中添加以下配置便可

<!-- 配置全站錯誤頁面 -->

<error-page>

    <error-code>404</error-code>

    <location>/404.jsp</location>

</error-page>

<error-page>

    <error-code>500</error-code>

    <location>/500.jsp</location>

</error-page>

 

 

 

  1. 定時器掃描過時訂單

    1. 定時任務介紹

  1. Timer回顧

 

 

 

 

  1. 定時掃描過時訂單並設置爲過時

    1. 建立監聽器,監聽ServletContext啓動

 

需求:定時掃描過時訂單並設置爲過時

 

1定時掃描,須要用到Timer TimeTask 類,在哪裏使用這兩個類?

須要在項目啓動的時候,掃描訂單。

 

2:什麼對象能夠監控到項目啓動

    ServletContextListener,能夠監聽項目啓動和關閉

 

3:定時器中的任務是什麼?

 

    獲取狀態爲1的訂單,比對建立時間,若是時間超出兩個小時,就設置過時(狀態:3)

 

 

註冊監聽器

package cn.itcast.listener;

 

import java.util.Timer;

import java.util.TimerTask;

 

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

 

import cn.itcast.service.OrderService;

import cn.itcast.service.impl.OrderServiceImpl;

 

public class SaoMiaoListener implements ServletContextListener{

 

    @Override

    public void contextInitialized(ServletContextEvent sce) {

        //開啓定時掃描任務

        //建立定時器

        Timer timer = new Timer();

        timer.schedule(new TimerTask() {

              

            @Override

            public void run() {

                System.out.println("===================定時掃描過時訂單啓動================");

                //調用service方法,執行定時任務

                OrderService orderService = new OrderServiceImpl();

                orderService.saomiao();

                System.out.println("===================定時掃描過時訂單完成================");

            }

            //0:當即執行

            //1000*60*60*2:兩個小時執行一次

        }, 0 ,1000*60*60*2);

          

        //2:00:00 定時器啓動 2:20:00,建立了訂單 4:00:00 定時器啓動 6:00:00 定時器啓動,訂單早已通過期

        //每個訂單,都設置一個定時器。

        //每個訂單創建,都會在內存中建立一個定時器對象,並且這個定時器對象必定要兩個小時以後才關閉

        //在線支付,判斷,只要訂單過時了,直接設置狀態爲3

    }

    

    @Override

    public void contextDestroyed(ServletContextEvent sce) {

    }

 

}

 

配置文件:

 

  1. Service實現

接口:OrderService

 

/**

     * 掃描過時訂單的方法

     */

    void saomiao();

 

 

實現類:OrderServiceImpl

public void saomiao() {

        // 定時任務:獲取全部狀態爲1訂單,而後,若是超出時間(2個小時),修改狀態:3

        //第一步:獲取全部狀態爲1訂單

        List<Order> list = orderDao.findByStatus(1);

        //第二步:循環遍歷,作判斷

        for (Order order : list) {

            //第三步:比較時間,如今的時間減去提交訂單的時間,大於兩個小時,狀態改成3

              

            long now = new Date().getTime();

            long time = order.getCreatetime().getTime();

            if(now - time >= 1000*60*60*2){

                //第四步:修改狀態爲3

                orderDao.updateStatus(3,order.getId());

            }

        }

    }

 

  1. Dao實現

接口:OrderDao

 

/**

     * 獲取指定狀態的訂單

     * @param i :指定狀態

     * @return

     */

    List<Order> findByStatus(int i);

 

    /**

     * 修改指定的訂單狀態

     * @param i

     * @param id

     */

    void updateStatus(int i, String id);

 

實現類:OrderDaoImpl

 

@Override

    public List<Order> findByStatus(int i) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "select * from orders where status = ?";

        try {

            return qr.query(sql, new BeanListHandler<Order>(Order.class), i);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("查詢指定狀態的訂單失敗");

        }

    }

 

    @Override

    public void updateStatus(int i, String id) {

        QueryRunner qr = new QueryRunner(DBUtils.getDataSource());

        String sql = "update orders set status = ? where id = ?";

        try {

            qr.update(sql, i,id);

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("修改指定的訂單狀態失敗");

        }

    }

 

  1. 在線支付

    1. 在線支付介紹

ICBC 工商銀行

 

在線支付流程一:

總結:商城經過第三方平臺和全部銀行交易

在線支付流程二:

 

 

  1. 易付寶支付介紹

易寶支付官網:https://www.yeepay.com/

 

易寶會給商家提供對應的支付接口以及文檔,開發人員在開發支付功能的時候,

只須要按照文檔中的說明直接完成對應的代碼便可。

 

支付接口及文檔下載:

 

  1. 編寫orders.jsp頁面上的支付連接

1)在訂單明細頁面上添加支付按鈕(未支付的訂單纔有,發送訂單編號和金額)

效果:

 

  1. 編寫pay.jsp

  1. 修改表單提交請求路徑
  2. 將訂單編號和金額寫入隱藏域
  3. 給用戶顯示訂單編號和金額

 

  1. 支付的Servlet實現

 

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.utils.PaymentUtil;

 

/*

* 支付的Servlet程序

*/

public class PayServlet extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 獲取訂單號、金額、銀行編碼

        String orderid = request.getParameter("orderid"); // 訂單號

          

        String money = request.getParameter("money"); // 金額

        String pd_FrpId = request.getParameter("pd_FrpId"); // 銀行編碼

 

        // 根據易寶接口準備參數

        String p0_Cmd = "Buy";

        String p1_MerId = "10001126856"; // 商家編號 10001126856

        String p2_Order = orderid; // 訂單號

        String p3_Amt = "0.01"; // 金額,單位是元

        String p4_Cur = "CNY";

 

        String p5_Pid = "";

        String p6_Pcat = "";

        String p7_Pdesc = "";

        // 支付成功回調地址 ---- 第三方支付公司會訪問、用戶訪問

        // 第三方支付能夠訪問網址

        // 須要獨立外網網卡

        String p8_Url = "http://127.0.0.1:8080/estore2/callback"; // 回調地址

        String p9_SAF = "";

        String pa_MP = "";

        String pr_NeedResponse = "1";

 

        // 將全部數據,進行數字簽名,加密算法由支付公司提供:註冊時,第三方支付平臺提供給商家的加密算法的摘要

        String keyValue = "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl"; // 密鑰

        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);

 

        // 將全部數據發送易寶指定地址

        request.setAttribute("pd_FrpId", pd_FrpId);

        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.setAttribute("p5_Pid", p5_Pid);

        request.setAttribute("p6_Pcat", p6_Pcat);

        request.setAttribute("p7_Pdesc", p7_Pdesc);

        request.setAttribute("p8_Url", p8_Url);

        request.setAttribute("p9_SAF", p9_SAF);

        request.setAttribute("pa_MP", pa_MP);

        request.setAttribute("pr_NeedResponse", pr_NeedResponse);

        request.setAttribute("hmac", hmac);

 

        // 跳轉確認支付頁面

        request.getRequestDispatcher("/confirm.jsp").forward(request, response);

 

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);

    }

 

 

}

 

 

  1. 支付確認頁面confirm.jsp

  1. 顯示訂單編號和訂單金額
  2. 隱藏域中都是servlet中封裝給易寶的數據

 

  1. 回調函數Servlet

package cn.itcast.web;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import cn.itcast.utils.PaymentUtil;

 

@SuppressWarnings({"serial","unused"})

public class CallbackServlet extends HttpServlet {

 

    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");

        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");

 

        // 將響應全部數據加密,比較hmac

        String keyValue = "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl";

        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")) {

                // 給用戶提示付款成功,查看付款結果

                System.out.println("收到1提示用戶,已經付款");

                response.setContentType("text/html;charset=utf-8");

                response.sendRedirect(request.getContextPath() + "/pay_success.jsp");

            } else if (r9_BType.equals("2")) {

                // 收到易寶到款通知,修改訂單狀態

                System.out.println("收到2 修改訂單狀態....");

                  

            }

        } else {

            throw new RuntimeException("數字簽名錯誤,假冒易寶!");

        }

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);

    }

 

}

 

 

 

 

相關文章
相關標籤/搜索