小米商场系统的购物网站的具体的功能实现(重点讲下订单的生成)

本文主要介绍了小米商场系统购物网站的前端功能实现,包括注册登录、主页展示、购物车、订单生成及支付流程。通过自封装的框架实现业务逻辑,详细讲解了数据库设计和关键功能的实现细节,如短信验证码、连接池、文件上传工具类以及UUID生成。文章还强调了数据表设计的重要性,并提供了部分表结构。
摘要由CSDN通过智能技术生成

小米商场系统的购物网站的具体的功能实现(重点讲下订单的生成)

一.需求分析
对于一个常用的购物网站,无非就是前台和后台,前台有相对于的注册和登录功能,负责数据的展示还有其购物车的生成,订单的生成,支付的功能,后台具有对数据的分类的功能,用户的信息的管理功能,相关的增删改查,对应一般的增删改查我们就不在一一的去讲解了,现在咱们这篇文章咱们主要讲解前台的功能的实现,就是咱们原来的在网上购物的实现,可能功能没有正式上线的功能那么强大,但是基本的功能咱们都能够实现的,下面我简单列下相关的前台的功能模块:

1.注册和登录模块
2.主页数据的展示的模块和点击详情的模块
3.加入购物车模块
4.生成订单模块
5.购物模块

二.准备工作
首先会创建一个web项目,因为现在没有学maven和框架,没有用maven工程,就自己封装了一个下框架,也能够简单实现功能,三层架构实现其业务逻辑,利用接口编程,便于控制,导入相对于的jar包,特别是支付的接口一定要特别注意

在这里插入图片描述
因为前后台很多很多的功能,封装了一个框架(下面会讲到),三层架构会不断的实现其特点,我这里就主要以控制成层为例,看一下其包结构
在这里插入图片描述
常用的JavaBean实体类对象
在这里插入图片描述
支付接口的相关的页面
在这里插入图片描述
常见的包结构,这里就不一一来详说其每一个特点了
在这里插入图片描述
二.相关的具体细节
1.封装了一个简单的框架
用于没有用到框架技术,里面有大量的相关的功能的实现,如果单纯使用servlet和jsp等页面的话,估计就上百个servlet了,严重影响代码的书写性,故实现了一个框架的封装,继承了我们常用的htttpServlet,重写了service方法,使其功能不断的增强

~~~java
package cn.ujiuye.utils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
/**
 * @author liugang
 * @date 2019/9/24
 * 封装一个servlet,继承HttpServlet,对其功能有个提升
 */
public class BaseServlet extends HttpServlet {

    //重写service方法
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取从前端页面传递过来的变量
        String method = request.getParameter("method");
        //获取当前类(继承该servlet的子类)的字节码对象
        Class clazz = this.getClass();
        //显然对从前端获取的数据做了非空性判断
        if (method == null || method.trim().length() == 0){
            method = "demo";
        }
        try {
            //利用反射技术获取当前类对象的方法
            Method clazzMethod = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
            String path = (String) clazzMethod.invoke(this, request, response);
            //对返回的结构做相对应的转发的操作 在其子类中只要做好相对应的返回功能即可
            if (path != null){
                request.getRequestDispatcher(path).forward(request,response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

二,获取短信验证码的功能封装一下
我们一般登录网站的时候常用的有验证码验证,输入自己的账号和密码然后在数据库中去寻找自己的信息,匹配了再完成登录,将自己的信息都存入到相关的域对象中去,在整个网站中都能显示我们的个人用户的信息,此时调用的就是session对象域,有的时候我们登录的就是短信验证,本次我们学习的就是阿里云,这个过程比较简单,但是对于新手还有专心的学习一下

package cn.ujiuye.utils;
import javax.servlet.http.HttpSession;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
public class SendCodeUtils {
    public static int sendCode(String phone, String RandomCode) throws Exception {
        //设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        //初始化ascClient需要的几个参数
        final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
        final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
        //替换成你的AK
        final String accessKeyId = "LTAI4FumJvdk2tScGNhfmD77";//你的accessKeyId,参考本文档步骤2
        final String accessKeySecret = "O9MhEi98iCpnxoYLN7D0AprNlrg2QM";//你的accessKeySecret,参考本文档步骤2
        //初始化ascClient,暂时不支持多region(请勿修改)
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
                accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象
        SendSmsRequest request = new SendSmsRequest();
        //使用post提交
        request.setMethod(MethodType.POST);
        //必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为国际区号+号码,如“85200000000”
        request.setPhoneNumbers(phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName("中公培训机构实战项目");
        //必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
        request.setTemplateCode("SMS_174811105");
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        //友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
        request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"" + RandomCode + "\"}");
        //可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");
        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        request.setOutId("yourOutId");
        //请求失败这里会抛ClientException异常
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
            //请求成功
            return 2;
        }
        return 1;
    }
}

3.连接池工具类
数据库连接池druid,封装成一个工具类,便于后面对数据的调用,从数据库中调用数据

~~~java
package cn.ujiuye.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类 使用Durid连接池
 */
public class JDBCUtils {
    private static DataSource ds ;
    static {
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            //使用ClassLoader加载配置文件,获取字节输入流
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);

            //2.初始化连接池对象
            ds = DruidDataSourceFactory.createDataSource(pro);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取连接池对象
     */
    public static DataSource getDataSource(){
        return ds;
    }
    /**
     * 获取连接Connection对象
     */
    public static Connection getConnection() throws SQLException {
        return  ds.getConnection();
    }
}

4.文件上传的工具类
该系统中不仅有刚注册中头像的上传还有各种各样的商品的信息需要我们不断的和文件打交道,将该功能封装成一个工具类,便于自己对文件进行操作,还有对图片的操作

package cn.ujiuye.utils;
import javax.servlet.http.Part;
/**
 * @author liugang
 * @date 2019/9/27
 * 文件上传的工具类
 */
public class FileUploadUtils {

    public static String getPic(Part part, String path, String pic) throws Exception {
        if(part.getSize()>0) {
            String fileInfo = part.getHeader("Content-disposition");
            //form-data; name="uphoto_img"; filename="pikaqi.jpg"

            String fileName = fileInfo.substring(fileInfo.indexOf("filename")+10, fileInfo.length()-1);
            //pikaqi.jpg
            String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
            //后缀 png  jpg  jpeg
            if("png".equals(suffix)||"jpeg".equals(suffix)||"jpg".equals(suffix)) {
                //文件格式合法
                //生成唯一的图片名称
                fileName = UUIDUtils.getCode()+"."+suffix;
                part.write(path+fileName);
                return fileName;
            }else {
                return null;
            }
        }else {
            return pic;
        }
    }
}

5.UUID生成id的工具类
因为该系统里面可能含有大量的文件和图片,怎么能够让这些图片不重复命名的呢,此时遍有了这个工具,保证我们使用的每一个图片和文件的命名都是唯一的

package cn.ujiuye.utils;
import java.util.UUID;
public class UUIDUtils {
	/**
	 * 随机生成id
	 * @return
	 */
	public static String getId(){
		return UUID.randomUUID().toString().replace("-", "").toUpperCase();
	}
	
	/**
	 * 生成随机码
	 * @return
	 */
	public static String getCode(){
		return getId();
	}
	
	public static void main(String[] args) {
		System.out.println(getId());
	}
}

三.数据库和数据表设计
首先数据库的设计,常用的数据库的命名首先要尽可能的和项目的名称保持一致,常用的命名的格式多数都是首字母的组合
在这里插入图片描述
接下来就是数据表的设计,我相信每一个项目数据表的设计都是重中之重,好的数据表的设计,都能够让你后期的项目更加强壮和后台业务逻辑的书写的更加顺利,反正我认为这个步骤特别特别的重要,首先分析这个项目,我建了5个表,它们分别是用户表user,商品类型表category,商品表goods,购物车表category和订单表Orders,下面我重点讲解一下用户表和购物车表和订单表之间的关系
用户表:
在这里插入图片描述
购物车表:
在这里插入图片描述
订单表
在这里插入图片描述
在这里插入图片描述
四.详细功能的实现
1.注册登录模块
1.1注册和登录的jsp页面,不管是注册还是登录,主要是发送请求,注册成功后跳转到登录的界面,其中主要有对数据的校验,发送ajax请求

~~~java
注册的页面功能的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
    <link rel="stylesheet" href="css/index.css">
	<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
	<script>
		function submit() {
			$("#form1").submit(); /*提交form表单*/
		}
		//文档就绪
		$(function () {
			//鼠标移除来的时候就对数据进行校验,判断其是否能够实现监听
			$("[name=uphone]").blur(function () {
                 var phone = this.value;
                 if (phone.trim()==""){
                     return;
				 }
                 //对你输入的手机号进行正则验证
				 var reg = /^1[3-9]\d{9}$/;
                 var flag = reg.test(phone); //true or false
				 if (!flag){
				 	$("#uphone_msg").text("手机格式不正确");
				 }else {
					 $("#uphone_msg").text("");
				 	//格式输入正确后,发送ajax到后台,验证该用户号码是否已被注册过
					 $.post("${pageContext.request.contextPath}/userServlet",{phone:phone,method:"checkPhone"},function (data) {
						 alert(data);
					 })
				 }

			})
		});
	</script>
</head>
<body>
<body>
<div class="sign_background">
    <div class="sign_background_in">
        <div class="sign_background_no1">
            <a href="index.html"><img src="img/logo.jpg" alt=""></a>
        </div>
        <div class="sign_background_no2">注册小米帐号</div>
        <div class="sign_background_no3">
               
            <div class="sign_background_no5">
             	${msg} <%--返回的数据如果不合适的数据   enctype="multipart/form-data" 将数据该成了这样,这种形式支持文件和图片上传和下载 --%>
             	<form id="form1" action="${pageContext.request.contextPath}/userServlet" method="post" enctype="multipart/form-data">
					<%--name=register--%>
             	    <input type="hidden" name="method" value="register">
             		<table style="width: 500px;" border="0" cellspacing="0">
             			<tr>
             				<td width="25%" class="_left">姓名:</td>
             				<td><input type="text" name="urealname"></td>
             			</tr>
             			<tr>
             				<td width="25%" class="_left">性别:</td>
             				<td>
             					男<input type="radio" name="usex" value="1">
             				 	女<input type="radio" name="usex" value="0">
							</td>
             			</tr>
             			<tr>
             				<td width="25%" class="_left">电话号码:</td>
             				<td><input type="text" name="uphone"></td>
							<td><span id="uphone_msg" style="color:red;"></span></td>
             			</tr>
             			<tr>
             				<td width="25%" class="_left">所在地区:</td>
             				<td><input type="text" name="uaddress"></td>
             			</tr>
             			<tr>
             				<td width="25%" class="_left">账号:</td>
             				<td><input type="text" name="uname"></td>
             			</tr>
             			<tr>
             				<td width="25%" class="_left">密码:</td>
             				<td><input type="password" name="upwd"></td>
             			</tr>
             			<tr>
             				<td width="25%" class="_left">上传头像:</td>
             				<td><input type="file" name="uphoto_img"></td>
             			</tr>
             		</table>
             		<div class="sign_background_no6" id="btn" onclick="submit()" >立即注册</div>
             	</form>
             	 
            </div>
        </div>
        <div class="sign_background_no7">注册帐号即表示您同意并愿意遵守小米 <span>用户协议</span>和<span>隐私政策</span> </div>
    </div>
    <div class="sign_background_no8"><img src="img/sign01.jpg" alt=""></div>

</div>
</body>
</html>

登录的jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    <link rel="stylesheet" href="css/index.css">
    <script src="js/jquery.1.11.1.min.js"></script>
    <style>

    </style>
<script type="text/javascript">
//读秒的方法
var iTime = 59;
var Account;
function RemainTime(){
	document.getElementById('zphone').disabled = true;
	var iSecond,sSecond="",sTime="";
	if (iTime >= 0){
		iSecond = parseInt(iTime%60);
		iMinute = parseInt(iTime/60)
		if (iSecond >= 0){
			if(iMinute>0){
				sSecond = iMinute + "分" + iSecond + "秒";
			}else{
				sSecond = iSecond + "秒";
			}
		}
		sTime=sSecond;
		if(iTime==0){
			clearTimeout(Account);
			sTime='获取手机验证码';
			iTime = 59;
			document.getElementById('zphone').disabled = false;
		}else{
			Account = setTimeout("RemainTime()",1000);
			iTime=iTime-1;
		}
	}else{
		sTime='没有倒计时';
	}
	document.getElementById('zphone').value = sTime;
}

/*对手机号做校验*/
function checkUphone() {
    var phone = $("#phone_number").val();
    if (phone.trim()==""){
        //提示:请输入手机号码
        $("#uphone_msg").text("请输入手机号码");
        return;
    }
    //对你输入的手机号进行正则验证
    var reg = /^1[3-9]\d{9}$/;
    var flag = reg.test(phone); //true or false
    if (!flag){
        $("#uphone_msg").text("格式不正确");
    }else {
        //格式正确后,通过ajax发送到后台,验证该手机号是否被注册过不
        $.post("${pageContext.request.contextPath}/userServlet",{phone:phone,method:"checkPhone2"},function (data) {
             if (data=="0"){  //手机号码尚未注册
                 $("#uphone_msg").text("请先注册");
             }else if (data == "1"){ //手机号码已被注册,验证码发送不成功
                 $("#uphone_msg").text("验证码发送失败");
             }else {    //验证码发送成功
                 $("#uphone_msg").text("");
                 RemainTime();
             }
        });

    }
}
/*获取登录的手机号码和验证码*/
$(function () {
    $("#sub").click(function () {
        //获取到手机登录的手机号码和验证码
        var phone = $("#phone_number").val();
        var code = $("#code").val();
        location.href="${pageContext.request.contextPath}/userServlet?method=checkLogin&phone="+phone+"&code="+code;
    })
})


</script>
</head>
<body>
<div class="register_head_on">

</div>
<div class="register_head">
    <a href="index.html"><img src="img/logo.jpg" alt=""></a>
    <div class="register_head_right">
        <p class="register_head_right_p1">小 米 商 城</p>
        <p class="register_head_right_p2">让每个人都享受科技乐趣</p>
    </div>

</div>

<div class="register">
    <div class="register_boby">
        <div class="register_boby_min">
            <div class="register_boby_no1">
                <div class="register_boby_no1_in">
                    <span style="color: #ff6700">手机验证码登录 </span>
                </div>
            </div>
            <span id="uphone_msg">${msg}</span>
            <form id="f3" action="userServlet" method="post">
            
            <!-- fs区分的方法 -->
            <input name="fs" value="checkCode" type="hidden">
            
            <div class="register_boby_no2">
            	<span id="msg" style="color: red;font-size: 12px;margin-left: 20px;"></span>
                <input id="phone_number" name="uphone" type="text" placeholder="手机号码">
                
                <input name="code" id="code" type="text" placeholder="手机校验码" style="width: 200px; margin-left: 15px;float: left;">
         
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值