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

    }

 

}

 

 

 

 

相关文章
相关标签/搜索