基于JAVA WEB的网上书店的设计与实现

摘 要

互联网的迅速发展为人们提供了更多的购物方式,网上商店就是目前最主流的网上购物方式之一。本网上购物系统的设计源于对网上购物需求的增加,由于地理位置购物不便,购物管理不规范,管理工作效率低的现状开发设计而成,人们可以足不出户,在电脑前就可以获得自己所需要的商品。网上购物将传统的购物流程数字化,可以大量减少人力、物力;另一方面突破了时间和空间的限制,使得交易活动可以在任何时间、任何地点进行,极大地方便了消费者,使购物过程变得轻松、快捷、方便,从而大大提高了效率。本论文设计就是利用JSP技术开发网上购物系统的事例。

本网上购物系统采用模块化程序设计方法,使用Oracle10g进行数据库开发。本系统充分利用了Jsp+Sruts+Javabean+Jstl+Hibernate+Orcle的简单组合,采用MVC设计模式,具备数据查询、修改、增加、删除、维护等功能,可以实现会员信息管理管理、订单管理、产品信息管理、购物车管理等功能。系统具有高可靠性、可扩展性和重用性的特点,为顾客提供一个便利的购物平台。界面设计使用了Dreamwaver;工具运用了Eclipse、JDK和Tomcat,后台数据库使用了Oracle。

关键词:网上购书系统;Hibernate;Struts;Oracle10g;MVC模式

ABSTRACT

With the development of the internate technology,It provides much more shopping styles .Shopping online is one of the most popular shopping style in the world. The e-commerce portal system design stems from domestic demand to increase in online shopping, shopping inconvenient Because of its geographical location, shopping management was not standardized, low-efficient management of the development and design from the status quo.

The reference to e-commerce portal system is modular in design procedures, the use of Oracle10g database development. The system made full use of Jsp + struts + Javabean + Jstl + Hibernate + Orcle a simple combination of using MVC design pattern, a data query, modify, add, delete, maintenance, and other functions, members can achieve the management information management, order management, product Information management, shopping cart management functions. to provide customers with the A convenient shopping platform. Interface design uses Dreamwaver; tools used Eclipse, JDK and Tomcat, background database using Oracle.

Keywords: Online bookstores; Hibernate;Struts; Oracle10g; MVC model

1 概述

1.1 课题的提出

电子商务始于20世界70年代,但当时主要是电子数据交换(EDI)贸易,应用不是很广泛而且交易量很小。随着Internet的不断普及,人们对网络应用的要求已经不再是浏览网站新闻、收发电子邮件,日益忙碌的人们开始追求利用互联网这一快捷而且强大的平台足不出户地进行网上购物。下面我们就以网上购书来比较网络销售较之传统市场营销所具有的特点:

第一、从间接经济到直接经济,交易成本降低

传统的市场营销模式必须有许多中间环节,图书出版商与消费者之间存在大量的批发商、零售商为中介,这就决定了其“间接经济”的特点。网络购书的出现从根本上减少了传统售书的中间环节,缩短了供与求之间的距离,同时也大大减少了各种不必要的消耗,使我们进入“直接经济”时代。网上书店的网上服务也可以提供全新的服务方式。网上购书使得买卖双方的交易成本大大降低,具体表现在:

  • 购书者和售书者通过网络进行商务活动,无需中介者参与,减少了交易的有关环节,所以网上书店的书的价格比传统书店低

  • 售书方可以通过互联网进行书籍的介绍,宣传,避免了在传统方式下做广告等大量费用

  • 互联网使买卖双发即使沟通供需信息,使无库存销售成为可能,从而使库存成本降为零

  • 传统的售书平台使地面地铺,新的网上书店的售书平台则使在网吧、家庭或者办公室

第二、让购书者的购买区域从当地扩展到全球

由于传统售书模式的限制,购书者往往只能在当地书店选购书籍,很少有人会为了买一本书特地去别的省市,即便让人代购也烦人烦己,而且各个书店的进货渠道有所不同,使得书店销售的书目品种存在差异,这就会让购买者要多跑几家才可能买到想要的书。互联网能够把全世界的顾客送到地球上开设的任何一家网络书店,消费者只需要在

电脑面前就跨市、跨省甚至跨国选购自己想要的书籍,这家网上书店如果需求,只需要鼠标一点即可进入另外一家网上书店,方便快捷,省钱省力。

第三、大小书店公平竞争,交易透明化

互联网为所有书店提供了平等的竞争环境。在传统售书行业中,出版商和销售商必须投入巨大资金和人力去建立其营销网络,对于一些中小书店来说,是一个非常庞大的障碍。然后现在,互联网使最小的书店也可以与最大的书店一样平等地出现在全世界的客户面前,像销售渠道之类的障碍在网络经济时代完全瓦解了。买卖双方整个交易过程都在网络上进行。通畅、快捷的信息传输可以保证各种信息之间相互核对,可以防止伪造信息的流通。

1.2 课题研究的目的和方法

系统的主要设计目的就是利用现代化的电子及网络技术,为企业和客户搭建一个互动平台——网上购书系统。降低企业运营成本的同时,方便客户购书,达到双赢的目的。一方面,企业减少了地面店铺的租凭费用,减少了宣传货物的广告费用,减少了雇佣员工的费用;另一方面,电子及网络技术使得企业运作更加快捷方便,为企业赢得宝贵的时间和商机。对于客户来说,客户省去了逛书店的时间,同时可以将自己的需求迅速地反馈给企业,使自己的需求可以更好地得到满足。

本系统是在Windows XP环境下开发。本文的设计方法是建立在MVC模式下的:用JSP做显示,用Struts做控制,用JavaBean连接Oracle数据库,并用Hibernate实现数据持久化,实现客户的注册、登陆、查找、购买、购物车管理、订单管理等功能,最终实现网上购书系统。

2 开发技术与工具

2.1 开发技术

2.1.1 Struts技术

Struts2的体系与Struts1体系的差别非常大,因为Struts2使用了WebWork的设计核心,而不是Struts1的设计核心。Struts2中大量使用拦截器来处理用户的请求,从而允许用户的业务逻辑控制器与Servlet API分离。

Struts2框架的大概处理流程如下:

  • 加载类(FilterDispatcher)

  • 读取配置(struts配置文件中的Action)

  • 派发请求(客户端发送请求)

  • 调用Action(FilterDispatcher从struts配置文件中读取与之相对应的Action )

  • 启用拦截器(WebWork拦截器链自动对请求应用通用功能,如验证)

  • 处理业务(回调Action的execute()方法)

  • 返回响应(通过execute方法将信息返回到FilterDispatcher)

  • 查找响应(FilterDispatcher根据配置查找响应的是什么信息如:SUCCESS、ERROER,将跳转到哪个jsp页面)

  • 响应用户(jsp—>客户浏览器端显示)

Struts框架的工作流程图

2.1.2 Hibernate技术

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

Hibernate的核心接口一共有5个,分别为:Session、SessionFactory、Transaction、Query和Configuration。这5个核心接口在任何开发中都会用到。通过这些接口,不仅可以对持久化对象进行存取,还能够进行事务控制。下面对这五个核心接口分别加以介绍。

Session接口

Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句。)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。

SessionFactory接口

SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。

Configuration接口

Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。在Hibernate的启动的过程中,Configuration类的实例首先定位映射文档位置、读取配置,然后创建SessionFactory对象。

Transaction接口

Transaction接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。

Query和Criteria接口

Query和Criteria接口负责执行各种数据库查询。它可以使用HQL语言或SQL语句两种表达方式。
要使用Hibernate技术需要将相应的JAR包放在开发路径下。

2.2 开发工具

2.2.1 开发工具-Tomcat

直接运行下载的apache-tomcat-6.0.18.exe文件,按照一般的Windows程序安装步骤即可安装好Tomcat,安装时它会自动寻找JDK的位置。安装过程中需要选择一个文件夹作为Tomcat的安装目录。我选择安装的位置是C:\Program Files\Apache Software Foundation\Tomcat 6.0。

安装完成以后,添加一个Tomcat的环境变量,添加方法和JDK的环境变量的添加方法相同,设置变量名为TOMCAT_HOME,变量值为C:\Program Files\Apache Software Foundation\Tomcat 6.0。

设置完毕后就可以运行Tomcat服务器了。Tomcat成功启动后,在浏览器中输入http://localhost:8080/ ,如果出现欢迎界面,则说明Tomcat安装成功。

2.2.2 开发工具-Oralce

概论

ORACLE 数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一。比如SilverStream就是基于数据库的一种中间件。ORACLE数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能;作为一个关系数据库,它是一个完备关系的产品;作为分布式数据库它实现了分布式处理功能。但它的所有知识,只要在一种机型上学习了ORACLE知识,便能在各种类型的机器上使用它。

特点

  • 完整的数据管理功能

    • 数据的大量性
    • 数据的保存的持久性
    • 数据的共享性
    • 数据的可靠性
  • 完备关系的产品

    • 信息准则—关系型DBMS的所有信息都应在逻辑上用一中方法,即表中的值显式地表示
    • 保证访问的准则
    • 视图更新准则—只要形成视图的表中的数据变化了,相应的视图中的数据同时变化
    • 数据物理性和逻辑性独立准则

2.2.3 开发工具-MyEclipse

MyEclipse企业级工作平台(MyEclipse Enterprise Workbench ,简称MyEclipse)是对EclipseIDE的扩展,利用它我们可以在数据库和JavaEE的开发、发布以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的JavaEE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML,Struts,JSP,CSS,Javascript,Spring,SQL,Hibernate。

3 需求分析

3.1 系统概述

本系统使用java语言及周边技术制作,为广大消费者提供一个网上购书的平台,便于对订单管理形成规范化,使信息资源可以有效的利用,极大的提高效率,减少工作量。该系统的功能模块主要由:用户信息自管理模块、购物车管理模块、订单管理模块、短信息模块、留言板模块,图书管理模块和订单处理模块组成。在后续章节中将详细介绍这些功能模块,系统结构总框架设计如图3.1所示:

3.2 技术可行性分析

使用java语言要比使用其他编程语言效率高,没有指针,代码中不进行内存管理,完全面向对象的语言由JVM和垃圾回收机制实现内存管理,跨平台一处编写处处运行,而且是多线程,在J2EE开发中使用一系列的框架从而使代码更加条理清晰,系统性能更加强大稳定,为编程人员提供快速和标准的应用接口,大大提高了应用软件的生产率。

在Web层使用Struts框架在持久化层使用Hibernate技术实现数据库中的表和代码中的实体类进行映射,对于业务逻辑和数据访问使用Javabean技术进行管理,层与层之间相互调用,所使用的模式有MVC模式,模型层就是业务逻辑层,处理业务逻辑、封装和传递数据,控制层由Struts框架下的Action完成,控制用户请求的转发,根据不同的要求转发到相应的显示层JSP进行显示。

MVC具体的处理过程如下:首先控制器接收用户的请求,并决定该调用哪个模型来进行处理;然后模型根据用户请求进行相应的业务逻辑处理,并返回数据最后控制器调用相应的视图来格式化模型返回数据;最后通过视图呈现给用户。

Struts有自己的控制器,同时整合了其他的一些技术去实现模型层和视图层,在模型层Struts可以很容易的与数据访问技术相结合,包括EJB、JDBC;在视图层Struts可以JSP,XSL等等这些表示层组相结合。

Struts框架是一个开源框架可以免费获得,使用WEB框架可以大大的提高开发软件的效率,在Struts框架中由Action实现控制转发请求,一般对每一个功能模块对应一个Action,从而使WEB开发变得轻松,愉快,在本系统的开发中充分利用了过滤器和监听器等功能是系统更加灵活的运行。

3.3 业务流程分析

为了提供系统的安全性,本系统使用用户的密码登陆方式登陆系统,增加系统数据的安全性、保密性,只有合法的用户才可以登陆系统。本系统主要功能是实现会员能够进行网上购书,为了更加完善系统的功能,又加入了留言板和收发信息等小模块。后台管理是为了给管理员提供方便,使系统功能功能更加完善。系统是建立在Struts框架上的,其中前台运用了Struts1框架,后台运用了Strusts2框架。系统结构总流程设计,如图3.2所示:

用户通过用户管理模块可以进行用户注册和登陆,用户通过购物车模块可以实现购买图书、修改购买图书数量等操作,用户通过订单管理模块实现将用户确认的订单保存到数据库,并且可以实现对用户订单和订单明细的查看操作。用例图如图3.3、图3.4所示:

管理员用例图

用户用例图

4 概要设计

4.1 数据库设计

数据访问层负责对业务层提供数据操作,也就是它负责和底层的数据库打交道。业务层或者通用层中所有的对象都通过数据访问层的对象访问数据库。数据访问层中的类是按业务对象来组织的,每个业务对象中包含的数据可能存在不同的几种数据表中,它由数据访问类统一组织成一个概念中的对象,它相当于是一个面向对象的数据库层,负责映射面向对象与关系数据库间的关系。

4.2 基本实体-联系图(ER图)

考虑到用户需求的各种实体,本系统规划出的实体有用户信息实体,产品信息实体、订单信息实体、订单明细信息实体,等等实体之间通过外键建立联系,在数据库中Hibernate技术,对数据库中的数据进行封装,一般是一张表影射成一个POJO类,通过类与类之间的关系来确立表之间的关系,在数据访问层通过HQL语句对数据库进行增删改查,通过Hibernate技术中相关的知识将数据信息持久化到数据库中,其中实体图如图4.1、图4.2、图4.3、图4.4、图4.5、图4.6所示:

说明:记录用户的基本信息

说明:记录图书的基本信息

说明:记录用户订单时的一些基本信息,客户编号参照客户的ID号

说明:记录订单明细的一些基本信息,订单编号参照订单信息的ID号,图书编号参照图书表的ID号

说明:记录用户留言时的一些基本信息

说明:记录用户发送和接受短息时的一些基本信息

基于系统的功能分析,其E-R图如4.7所示:

4.3 数据库逻辑结构设计

数据库在信息系统中占有及其重要的地位,数据库结构设计的好坏关系到系统的运行效率、存储数据的效率、系统的复杂程度等,合理的数据库结构设计可以提高系统性能。本网上购物系统数据分为前台和后台数据,分别是商品数据、订单数据、客户数据,订单明细数据,短信息数据,留言板数据等。将以上的数据库概念结构转化为关系数据模型,即数据库的逻辑结构。各个数据的字段设置如下表所示:

customer表

字段名 字段类型 约束或索引 描述
ID Number(Sequence) PK 记录流水号
Name Varchar2(20) 用户名
Password Varchar2(20) 用户密码
Zip Varchar2(20) 邮编
Address Varchar2(50) 地址
Telephone Varchar2(20) 电话
Email Varchar2 (30) 电子邮件

说明:ID用oracle的sequence的自增长

book表

字段名 字段类型 约束或索引 描述
ID Number(Sequence) PK 记录流水号
Name Varchar2(100) 商品名
Price Number(8,2) 价格
Author Varchar2(30) 作者
Publish Varchar2(50) 出版社

说明:ID用oracle的sequence的自增长

Orderform表

字段名 字段类型 约束或索引 描述
ID Number(Sequence) PK 记录流水号
Cost Number(8,2) 订单总额
Orderdate Date 下单时间
Customerid Number FK 记录流水号
Status Varchar2(40) 订单状态

说明:ID用oracle的sequence的自增长,Customerid参照用户的ID,Status标记订单的发送状态:未发送和已发送

Orderline表

字段名 字段类型 约束或索引 描述
ID Number(Sequence) PK 记录流水号
Num Number 数量
Orderid Number FK 订单的流水记录号
Bookid Number FK 商品的流水记录号

说明:ID用oracle的sequence的自增长,Orderid参照订单表的ID,Bookid参照书籍的ID

MessageRecord表

字段名 字段类型 约束或索引 描述
ID Number(Sequence) PK 记录流水号
Sender Varchar2(20) Not Null 发件人登录名
Receiver Varchar2(20) Not Null 收件人登录名
SendDate Date Default=当前时间 , Not Null 发送日期
Title Varchar2(100) Not Null 短信标题
Content Varchar2(300) Not Null 短信内容
Status Number Default=0 0-未阅1-已阅读
SenderStatus Number Default=0 0-未删1-已删除
ReceiverStatus Number Default=0 0-未删1-已删除

说明:ID用oracle的sequence的自增长,Status用0、1标记邮件是未读还是已读,SenderStatus用0、1标记在发送者端邮件是未删除还是已删除,ReceiverStatus 用0、1标记在接收者端邮件是未删除还是已删除

ForumMessage表

字段名 字段类型 约束或索引 描述
ID Number(Sequence) PK 记录流水号
Sender varchar2 Not Null 记录发送者
Title varchar2 Not Null 标题
SendDate Date Not Null 发送日期
Content varchar2 Not Null 发送内容

说明:ID用oracle的sequence的自增长

4.2 Web系统安全性的考虑

4.4.1 本系统中基本的安全性的实现

  • 利用一个后台服务器端的功能组件实现随机产生一个验证码,由于验证码是机器随机产生的,因此暴力破解程序无法预料到具体是什么,所以可以防止暴力破解

  • 系统的每个功能都必须经过身份验证后才能访问,没有认证的请求会被过滤掉,这是最基本的安全要求

  • 所有功能都通过Struts的Action来进行访问,不直接以jsp的形式向用户提供功能访问,这样一方面可以防止向用户暴露程序的资源名称,另一方面也可更方便的进行权限控制

  • 对用户的请求进行与其身份相匹配的识别

4.4.2 对Struts的ActionServlet设置Filter

利用该Filter来检查用户的权限,这样既可以防止用户登陆后跨url访问。在本项目中添加一个WebBBSFilter组件来监控后台管理的URL。

4.4.3 防止绕过权限认证的直接资源访问

虽然前面的设计中,已经要求所有的功能都通过struts的Action来进行访问,但是还是不能排除恶意用户可能会知道程序资源名称(jsp文件),如果这类用户直接输入jsp文件的url访问,有可能会对系统形成威胁。

5 详细设计及实现

5.1 用户管理模块

主页中由列出了系统推荐最新上架的商品和一些特价商品,任何游客都可以浏览主页的信息,但是要想使用本网上购物系统的功能必须登录成功才行。下面是本网上网书系统的主界面,如图5.1所示:

当客户登录成功后,用户可以输入要购买的商品数量点击购买即可将商品添加到购物车里,用户也可以查看或修改用户个人信息,也可以根据需要点击相应的链接发送短信息进入留言板,浏览货物信息等。在购物界面可以添加货物到购物车此处设计成一个Map集合,存放订购信息,Key为货号,Value为货物整个对象,可以循环购买货物,在没有提交确认前可以删除不需要的货物,提交确认后,网站会再一次确认你的地址,电话等,可以修改这些信息,以便,货物可以按时送到。

5.1.1 用户登录模块

在登录界面上可以实现两种用户的登陆,一是客户登陆,二是管理员的登陆。如果客户输入用户名和密码都正确,进入网上购物系统;管理员如果输入的用户名和密码正确则进入后台管理系统。如果用户名和密码不正确,提示用户失败登录,并重新登录。如果用户名和密码为空,通过Ajax验证提示用户输入用户名和密码。如果用户不存在还可以点击用户注册进入用户注册界面。在登录页面上还有一个Checkbox,如果用户登陆的时候选上的话,利用Cookie保存用户名和密码,则下次该用户再访问登录页面的时候,就可以实现自动登陆。如图5.2所示:

在登录界面上用户可以输入用户名和密码进行登录,如果用户名和密码正确,将成功跳转到图书系统主页面,如果不正确,提示给用户错误信息,并且还跳转到登录界面继续登录。

具体实现过程:首先客户端验证通过JavaScript来完成,比如用户没有输入用户名时会提示客户用户名不能为空,密码为空时提示密码不能为空。只有用户名和密码都填写好以后才能进行客户端数据的提交,这样使得操作更加方便并且提高效率。当数据提交以后,程序将数据提交给配置文件Struts-Config.xml中定义Struts高级特性UserDynamicForm,其类型为DynaActionForm,在UserDynameicForm中的Form-property属性中接收JSP界面中提交的用户名和密码,其类型为String类型。在UserAction中通过Login方法传入UserDynameicForm的用户名和密码,并且判断输入的用户名和密码是否正确,Login方法会调用ICustomerService接口中的Login方法实现登录的合法性验证,在此Service方法中首先要调用Dao方法中的FindCustomerByName 方法判断数据库Customer表中是否存在名字为Name的记录,如果不存在则提示用户输入的用户名不存在,如果存在,继续判断密码是否于数据库中的密码相同,相同的时候表示登录成功跳转到购书系统的主界面,否则跳转到登录界面继续登录。在登录成功以后在Login方法中把用户信息提交到Session范围内,以供程序后继使用用户的个人信息。

5.1.2 用户注册模块

第一次登陆的用户必须先注册,与注册界面有关的为Register.jsp,完成注册功能时需要在Struts-Config.xml中配置一个DynaActionForm,在Action包中的UserAction中定义一个Register方法,调用相应的Dao和Service方法实现注册。对注册的用户进行合法性的验证,满足所有的条件的用户才能注册成功。用户名作为用户登录的唯一标识。在验证注册新用户的过程中加入新加入了验证码验证的过程,如果在用户名不冲突验证码输入正确的情况下,才能注册成功,否则重新注册。注册界面如图5.3所示:

具体实现的过程:在注册界面中,对于带有红色星号的项必须填写,其具体的客户端验证通过JavaScript完成,如果没有填写在提交的时候系统会提示用户填写相关的项目。在JavaScript文件的Base.js中定义了一个ValidateRegisterForm函数,专门对注册界面提交的表单进行合法性验证,在JSP页面中通过Form表单的Onsubmit属性对把数据提交给Base.js进行判断,若验证通过,转回Form中执行Action属性,跳转UserAction的Register方法中,在Register中接收到UserDynamicForm中的JSP页面提交的相关数据,创建Customer对象并将提交的数据封装在Customer类中,调用Service中的Register方法对业务逻辑进行进一步的验证,完全符合条件的情况下才能注册成功,否则继续进行注册。代码实现过程中出现的问题:在对用户注册的合法性验证过程中,从JSP页面中提交的数据信息必须和传入JavaScript代码中属性的名称必须一致。

用户部分还有检查是否登录的功能,通过UserAction中CheckLogin方法实现,判断在Session对象内是否存在Customer对象,如果存在可以直接进入购书系统的主界面,如果不存在将跳到Login.jsp界面提示用户通过登录的方式进入系统。其主要实现同登录的实现。

5.1.3 用户退出系统操作

当用户退出系统时,用户必须重新登陆才可以进行网上购物等功能。用户单击系统顶部导航栏中退出按钮,会触发相应的ExitAction,用户退出系统,返回到主界面。如果用户想使用网站的其他功能必须重新登陆,成功登陆后进行相应的其他功能操作。

该功能主要是让Session失效,通过Session.invalidate()方法实现。

实现代码如下:

public class ExitAction extends Action{public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception{request.getSession().invalidate();return new ActionForward(“/login.jsp”);}
}

5.1.4 找回密码

当客户忘记密码的时候,可以访问找回密码页面,输入会员的帐号、密码提示问题、密码提示答案进行提交,系统对这些信息进行判断,如果正确,则产生一个新的密码返回给用户,并在页面上显示,提示用户下次要妥善保管好自己的密码,并将数据库中的密码修改成新密码。如果不正确,则提示用户。如图5.4所示:

5.1.5 用户信息修改

在整个购书系统中还可以对用户的个人信息进行动态的显示和修改,以及在密码丢失的情况下找回密码的功能。

用户的个人信息可以动态的显示在页面上,通过JSP页面向UserAction中传入新的需要修改的用户信息,并从Session对象中取出登录成功时存放在Session对象中的Customer对象信息,如果登录用户的密码输入正确时就可以对用户的个人信息进行修改,调用IOrderService中的UpdatePassword方法对输入的密码进行合法性的验证。个人信息列表如图4-5所示:

5.2 购物车管理模块

跟踪用户选择的商品,用户在购物车中保存浏览商店时所选中的商品。每个用户都有自己临时的一个购物车。可以查看购物车,可以向购物车中添加选中的商品,修改选中的商品的数量,删除已选择的商品或者清空购物车重新选购商品。

购物车的代码实现如下:

public class CartAction extends DispatchAction {public ActionForward addOrderLine(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {DynaActionForm cartDynamicForm = (DynaActionForm) form;HttpSession session = request.getSession();ServletContext stx = session.getServletContext();
Map<Long,Book> books = (Map<Long,Book>)stx.getAttribute("books");ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");  String bookid = cartDynamicForm.getString("bookid");String num = cartDynamicForm.getString("num");Book book = (Book)books.get(Long.parseLong(bookid));Orderline line = new Orderline();line.setBook(book);line.setNum(Long.parseLong(num));cart.addLine(line);return mapping.findForward("addSuccess");}public ActionForward deleteOrderLine(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {DynaActionForm cartDynamicForm = (DynaActionForm) form;HttpSession session = request.getSession();ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");String lineid = request.getParameter("lineid");cart.dropLine(Long.parseLong(lineid));return mapping.findForward("deleteSuccess");}public ActionForward editOrderLine(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {DynaActionForm cartDynamicForm = (DynaActionForm) form;HttpSession session = request.getSession();ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");String lineid =cartDynamicForm.getString("lineid");String num =cartDynamicForm.getString("num");Orderline orderline = cart.getOrderline(Long.parseLong(lineid));orderline.setNum(Long.parseLong(num));return mapping.findForward("editSuccess");}public ActionForward clearCart(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {DynaActionForm cartDynamicForm = (DynaActionForm) form;HttpSession session = request.getSession();ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");cart.removeAll();return mapping.findForward("clearSuccess");}
}

购物车的实现是本系统的核心技术部分,首先是购物车列表的动态显示,使用JSP中Use Bean标签实现。

图书列表的动态显示是在WEB应用启动的时候完成的,使用了创建事件监听器的方式实现。具体实现:创建一个ContextListener类,继承系统提供的ServletContextListener类,定义ContextInitialized方法对图书列表信息进行初始化工作,在此方法中调用IOrderService接口中的ListAllBook方法,从数据库中取出所有的图书信息,并把图书信息存放在ServletContext范围内的Application对象中,存放在ServletContext范围内的对象的生命周期为从WEB服务器的启动到WEB服务器的关闭时注销,因此解决了在整个系统运行的过程中都有图书信息的存在,而且不用在每次用到图书信息的时候去数据库中查询调用数据,减少了与数据库的交互性并能显著提高系统的运行效率。采用ContextDestroyed方法删除存放在ServletContext范围中的图书信息。

5.2.1 添加购物车

如果用户想购买商品可以直接点击右侧加入到购物车,所选择的商品便通过以下代码加入到用户自己的购物车中,如图5.6所示:

Action实现代码如下:

public ActionForward addOrderLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {    DynaActionForm cartDynamicForm = (DynaActionForm) form;HttpSession session = request.getSession();ServletContext stx = session.getServletContext();Map<Long,Book> books = (Map<Long,Book>)stx.getAttribute("books");ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");String bookid = cartDynamicForm.getString("bookid");String num = cartDynamicForm.getString("num");Book book = (Book)books.get(Long.parseLong(bookid));System.out.println("num is"+num);System.out.println("bookid is"+bookid);Orderline line = new Orderline();line.setBook(book);line.setNum(Long.parseLong(num));System.out.println("orderline is "+line);cart.addLine(line);return mapping.findForward("addSuccess");
}

5.2.2 查看购物车

用户购买商品后可以点击“查看购物车”查看购物车里的商品系统会跳转到购物车页面。购物车是通过一个监听器在系统启动时就在当前会话中创建一个购物车,当用户打开浏览器时系统自动把创建购物车放到Session中。当用户关闭浏览器时系统自动删除购物车。如图5.7所示:

监听器(Listener)代码实现如下:

public class SessionListener implements HttpSessionListener{public void sessionCreated(HttpSessionEvent arg0) {HttpSession session = arg0.getSession();ShoppingCart cart = new ShoppingCart();session.setAttribute("cart", cart);        }

5.2.3 清空购物车

如果客户看到自己又购物车里不想买的东西又可以点击“清空购物车”,来清空购物车中的商品,或者也可以点击“清除”按钮来清除某一件商品。

Action代码实现如下:

public String clearCart() {ActionContext context=ActionContext.getContext();ShoppingCart cart =(ShoppingCart)context.getSession().get("cart");cart.removeAll();return "success";
}

代码说明:从Session中获得购物车,直接调用ShoppingCart中的RemoveAll()方法即可。

5.2.4 修改购物车

如果想修改自己购买商品的数量可以输入具体的商品数量,并单击保存修改,如果想继续购买产品单击继续购物又可以跳转到购买页面,如果不想购买先前购物车里的产品单击清空购物车即可,最后确定购买,便可提交订单,生成定单就这么简单,在单击“提交定单”后进入确认定单页面,如图4-7所示。

当用户在购物车页面中点击“提交定单”按钮时便可以跳转到提交定单页面。其中当单击右侧的取消按钮时调用下面的Action修改这条购物清单,具体代码实现类似于清空购物车调用业务逻辑层相应的业务逻辑方法,然后在调用数据访问层的方法,从而作用于数据库中的数据,在业务层通过底层数据访问层利用HQL 语句查询实现对数据库中数据的同步和持久化。

5.3 订单管理模块

当确认订单后,系统根据购物车中的数据生成一个订单和一个订单明细表,并将所购买的商品信息加入到相应顾客的订单信息中,并清空购物车中的所有商品。其中在订单确认提交前可以对用户信息进行修改,这样方便了实际中客户信息变化的情况,增加了系统的功能,提高了系统的通用性。订单确认成功后便可以显示该用户的订单明细,可以供用户查看订单信息,以便再进行购买。系统返回到商品列表界面时,用户可以查询自己的订单情况,进而查询订单明细。

5.3.1 生成定单

当用户在购物车页面中点击提交定单按钮时便可以为客户生成一个订单,保存到数据库中,并可以列出该客户的基本信息和所购买的商品。如图5.8所示:

当该用户确认提交的定单之后,系统便会设置定单信息,包括金额,下单时间,客户信息等,并保存该定单信息,之后便会清空当前购物车中的内容。

代码实现如下:

public ActionForward confirm(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {DynaActionForm orderDynamicForm = (DynaActionForm) form;HttpSession session = request.getSession();ShoppingCart cart = (ShoppingCart) session.getAttribute("cart");Customer customer = (Customer) session.getAttribute("customer");double cost = cart.getCost();Orderform order = new Orderform();order.setCost(cost);order.setCustomer(customer);order.setOrderdate(new java.util.Date());Collection<Orderline> c = cart.getOrderlines();for (Orderline orderline : c) {orderline.setOrderform(order);order.getOrderlines().add(orderline);}IOrderService orderService = (IOrderService) BeanFactory.getBean(BeanFactory.ORDERSERVICE);try {orderService.saveOrder(order);request.setAttribute("message", "提交订单成功");request.setAttribute("order", order);cart.removeAll();return mapping.findForward("confirmSuccess");}  catch (OrderServiceException e) {request.setAttribute("message", e.getMessage());return mapping.findForward("confirmFailure");}
}

5.3.2 查看定单

用户在购物的过程中客户可以查看自己所有的定单有时查看自己所下的定单,显示客户的所下的定单。首先获得Session中当前的客户信息,然后根据客户ID调用Service层的ListAllorder()方法,从数据库中找出该客户所有的定单,再把从数据库中找出来的信息放到ActionContext中,再通过JSP显示出来。也可以点击“继续购物”返回购物首页。如图图5.9所示:

5.4 短信息管理模块

5.4.1 新建短信

客户与客户,客户与售货员及店长之间可以通过发送短信息进行交流,如果用户的短信息没有填写主题系统将提示用户填写主题,系统会判断接收者是否存在,如果存在,则发送,并且提示用户成功;如果不存在提示用户接收方不存在。如图5.10所示:

此处主要是用javascript作验证:

<script type="text/javascript">function sendInfo(form){var receiver=form.receiver.value;var title =form.title.value;if(/^\s*$/.test(receiver)){alert("please input the receiver!");return false;}if(/^\s*$/.test(title)){if (confirm("确定信息主题为空?")==false){return false;}}}
</script>

而发送的信息首先是将信息的内容、发送者、主题、信息状态通过业务逻辑层调用数据持久层将信息保存在Messagerecord表中进行持久化。

5.4.2 已接收短信

显示当前客户接收的所有短信(包括新短信和已读短信),并且可以删除某条短信,和查看某条短信的详细信息。

它实现的方法主要是根据(收件人)从数据库中找出该用户所有的短信息,并可以根据信息的状态可以区分已读和未读的短信息。当用户登录成功后即可在左边的导航栏的收件箱中显示该用户未读的短信息。用户可以查看短信息的内容或删除某条信。如图5.11所示:

5.4.3 已发送短信

显示当前客户已发送的所有短信(已经删除的除外),并且可以删除短信息。如图5.12所示:

5.5 客户留言坂模块

客户可以在这里在线留言,向店长反应商品的质量,服务态度,信用度等。当用户发表自己的留言后便可以看到自己刚才的留言,还可以查看到其他用户的留言信息,所有的信息都是根据发表的时间先后顺序排列的,后发表的排在前面。如图5.13所示:

实现的方法与短信息类似,首先也是将用发表留言的时间,内容等信息保存到数据库中,通过Action调用业务逻辑层的方法,业务层再调用数据层的方法,当用户信息发表成功之后系统会按发表时间分页显示所有的留言信息,每页显示4条。

5.6 订单处理模块

这个模块主要实现了对定单的处理,包括定单的删除、发货、查询订单的详细信息等。另外,系统还实现了对所查纪录进行分页显示的功能。

5.6.1 查看所有定单

此模块主要用于查询,所有管理员都可以查看定单的基本信息,并实现了分页显示的功能,可以查看这些定单的详细信息,对这些定单进行删除和发货等操作。界面如图5.14所示

5.6.2 处理定单

点击“处理订单”后会显示所有未发货的定单,并且可以查看这些定单的详细信息,对这些定单进行处理操作,并实现了分页显示的功能。主要是通过商品的发货状态来进行查找,实现方法与其他条件查询功能类似。界面如下图5.15所示:

5.7 图书管理模块

5.7.1 添加新图书

如果有新货要上架,就可以通过该模块添加新商品,管理员在JSP页面的表单中输入图书名称,图书作者,出版社,价格信息,并将表单提交到添加商品的Action中,通过Action去调用业务逻辑层和数据持久层的保存方法,将该商品数据库中,从而可以让客户在前台可以浏览到该商品。如图5.16所示:

5.7.2 编辑图书

可以再重新编辑图书的各个属性,管理员可以根据市场行情改变图书的价格或者其他属性。如图5.17所示:

5.7.3 搜索图书

功能:该模块主要实现用户搜索所要的图书,即用户可以根据自己的需要输入自己想要书的信息,提交即可搜索对应的书本。本搜索采用的是动态的模糊搜索,即读者只知道模糊的书本信息,输入后也可以查询到与输入字段相关的图书信息。如果搜索的信息不存在,就会弹出页面显示提示信息:搜索的图书不存在。如图5.18所示:

关键性代码如下:

public Page findSelectbook(String name, String author, String publish, long sortID, int findPage) throws MessengerServiceException {String strSql = null;strSql = "from Book where";strSql = strSql + " name like '%" + name + "%'";strSql = strSql + " and author like '%" + author + "%'";strSql = strSql + " and publish like '%" + publish+ "%'";if (sortID != 0)strSql = strSql + " and SortID =" + sortID;Transaction tran = new HibernateTransaction();tran.beginTransaction();Page page = null;try {page = page.findPage(strSql, findPage);tran.commit();} catch (Exception e) {e.printStackTrace();tran.rollback();}
}

5.8 关键技术及系统安全性能

5.8.1系统关键技术

创建业务逻辑层类

新建一个类。类名设定为“***Serivice”在这个类中定义本系统所用到的业务逻辑方法,由web层中的action进行调用相应的方法,实现web层和业务逻辑层之间的相互调用,降低层层之间的偶合性。

创建过滤器类和监听器类

本系统通过EncodeFilter来解决编码问题,并关掉Session.相关代码如下:

public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {arg0.setCharacterEncoding("UTF-8");arg1.setCharacterEncoding("UTF-8");arg2.doFilter(arg0, arg1);HibernateSessionFactory.closeSession();
}

本系统另外一个亮点是使用了监听器功能:

当用户关闭浏览器时系统自动删除购物车,用户打开浏览器时系统自动创建购物车放到Session中代码实现;启动WEB服务时,将图书加入ServletContext中,以便提高系统效率。其中过滤器和监听器必须在配置文件中作相应的配置才有作用,在Web.xml中配置

数据验证

Ajax它是Asynchronous JavaScript and XML的英文缩写,翻译过来就是“异步的JavaScript and XML”。可以说它是一种技术,更可以说它是一种技巧。其实它是多种技术的综合,包括JavaScript、XHTML和CSS、DOM、XML和XSTL、XMLHttpRequest。其中:使用XHTML和CSS标准化呈现,使用DOM实现动态显示和交互,使用XML和XSTL进行数据交换与处理,使用XMLHttpRequest对象进行异步数据读取,使用JavaScript绑定和处理所有数据。

本系统采用Ajax的异步请求局部刷新的技术进行用户注册信息数据(用户名唯一性)的验证。对用户注册模块的用户名作验证,检测昵称是否存在,电话号码是否全为数字,邮箱地址是否合法等。

5.8.2 系统安全性能

为了保证系统的安全性,操作人员进入本系统前必须输入与相关用户名对应的有效密码,并且对输入的数据进行字符的过滤,不知道密码的非操作人员进入本系统后,仅仅只能看到系统产品的信息,没有权限执行用户管理模块,购物车管理模块,订单管理模块,留言板模块等,不能在本系统中进行购物,不能对数据库中的数据进行增加,删除,改写,查询等操作,只有用户登陆后并且用户名和密码正确无误才可以有使用本系统的权限,才能够享受本平台提供的各项功能,方便、快速、高效的进行购物管理等功能。

6 系统测试与运行

6.1 系统测试

  • 用户注册:测试邮箱格式是否正确

  • 发送消息:编辑发送消息按钮,看是否成功

  • 购物车提交订单:点击提交订单之后,弹出确认界面,可以选择确认订单继续购物

6.2 系统部署及运行说明

打开PL/SQL Developer,点击“文件”—》“新建”—》“命令窗口”,弹出下图界面:

然后把SQL语句复制进去就把数据库还原进去了;进入Tomcat6的webapps目录

将本系统提供的目录下的estore.war复制到webapps下,如图所示

进入Tomcat目录下的bin,双击tomcat6.exe,开启tomcat服务,看到如下界面,则说明服务启动成功

7 总结和展望

通过这次毕业设计我觉得自己从中学到了很多。首先我对JavaWeb开发有了更深层的理解,对网站的架构以及架构模式的理解更深了一步,代码的编写让我能更为熟练的运用所学知识。我的热情并不会因为毕业设计的结束而结束,我会继续完善它,因为它是我的财富,对我来说学是无止境的,今后我会给自己一个不同的定位,使自己在今后的工作中、学习中不断提高,不断前进。

网站的设计、编写是一个辛苦而漫长的过程。从最初的构想开始,到中间的代码编写、完善再到最后的调试、完成,应该说这一路走下来,其中的甘苦真的只有自己来体会,当每个模块一步一步出现在我眼前时,我高兴得忘记这其中的处理那一片片程序异常时的痛苦。购物车、留言板、发信息等都是现在时兴的话题和技术,但对于我来说,没有太多可以借鉴的东西和事物,摸石头过河,既有艰难也有成功后的快乐,还有与同学们一起讨论的豁然开朗!在购物车制作中,考虑周全是一个很重要的问题,很多东西也话不一定马上用的到,比如很多的表和字段,但这些必须先要预留出来,这样对于下一步来说是很有利的,网站的编写过程也就是一个不断完善的的过程。

这个系统一开始是用JSP和Servlet写的,在JSP页面中嵌入了很多Java代码,那样不便于维护,后来又改用了Action进行控制,在JSP页面中又改为了EL表达式,而在学Struts2之后,在JSP页面中又改用了OGNL表达式,这样使JSP页面的汉字和Java代码更少了。

购物车模块是首先设计出来的,并尝试过用了好几种方式实现,在这个基础上我考虑到一些现实的需要增加了一些功能,比如留言板,短信息等,为我的购物系统增加了不少吸引顾客的功能!购物车完全用Struts框架来实现,并使用了新的技术JSTL标签库的功能,使得JSP页面上只有少量的Java代码和中文,这个网站还有很多很多的不足,比如:管理员模块功能简单,没有实现文件上传得功能,页面不够华丽,没有考虑到对数据库的备份操作以及权限的分配,系统安全性不高等问题,有待我去改善。

对于这个网站的完成,这只是一个开始。我以后更要在工作中积累经验和学习更深层次的知识,不断的充实自己,做出更好的系统软件。

参考文献

[1] Ivor Horton著.Java 2 入门经典 JDK5[M].潘晓雷 于浚泊,王丹等译.北京:机械工业出版社,2005.1-1058

[2] 刘甲耀,严桂兰.Core Java应用程序设计教程[M].北京:电子工业出版社,2005.2.97-304

[3] 孙卫琴.精通Struts:基于MVC的Java Web设计与开发[M].北京:电子工业出版社,2004.8.7-35

[4] 菜剑,景楠. Java Web应用开发:J2EE和Tomcat第2版[M].北京:清华大学出版社,2005.1.35-250

[5] 孙卫琴,李洪成.Tomcat与Java.Web开发技术详解[M].北京:电子工业出版社,2004.4.29-134

[6] 殷兆麟,张永平,姜淑娟.Java网络高级编程[M].北京:清华大学出版社,北京交通大学出版社,2005.5.94-235

[7] Marco Pistoia,Nataraj Nagaratnam等著.企业级Java安全性:构建安全的J2EE应用[M].尹亚,明喻卫,严进宝译.北京:清华大学出版社,2005.3,72-109

[8] 《深入浅出Java语言程序设计》 李云山,吕杰武.中国青年出版社,2003.2

[9] 《Java程序设计实践教程》 刘万军.清华大学出版社,2006.9

[10]林邦杰.JAVA程序设计入门教程.中国青年出版社,2001,416-528

基于JAVA WEB的网上书店的设计与实现相关推荐

  1. 网购图书java代码_基于JAVA WEB的网上书店的设计与实现

    摘 要 互联网的迅速发展为人们提供了更多的购物方式,网上商店就是目前最主流的网上购物方式之一.本网上购物系统的设计源于对网上购物需求的增加,由于地理位置购物不便,购物管理不规范,管理工作效率低的现状开 ...

  2. 基于java web的网上书店系统

    006基于java web的网上书店系统(含论文) 开发环境: Eclipse/MyEclipse.Tomcat8.Jdk1.8 数据库: MySQL 适用于: 课程设计,毕业设计,学习等等 系统介绍 ...

  3. java计算机毕业设计网上书店的设计与实现源程序+mysql+系统+lw文档+远程调试

    java计算机毕业设计网上书店的设计与实现源程序+mysql+系统+lw文档+远程调试 java计算机毕业设计网上书店的设计与实现源程序+mysql+系统+lw文档+远程调试 本源码技术栈: 项目架构 ...

  4. 毕业设计之 --- 基于java web的物流信息网的设计与实现

    文章目录 0 前言 1 课题背景 2 实现功能 2.1 系统流程设计 2.2 系统功能设计 2.3 数据流 2.4 数据库ER图 3 运行效果 4 部分实现代码 5 最后 0 前言 今天向大家展示学长 ...

  5. java web网上书城_基于Java web的网上书城

    源码编号:B-E00009点击查看分类规则 项目类型:Java EE项目(java web项目) 项目名称:基于Java web的网上书城(shinebookshop) 当前版本:V1.0.0版本 难 ...

  6. 毕业设计 基于java web的网上招标系统

    文章目录 前言 一.项目设计 1. 模块设计 注册用户部分 管理员部分 2. 实现效果 二.部分源码 最后 前言 今天学长向大家分享一个 毕业设计项目: 基于java web的网上招标系统 一.项目设 ...

  7. java计算机毕业设计网上书店的设计与实现源码+数据库+系统+lw文档+mybatis+运行部署

    java计算机毕业设计网上书店的设计与实现源码+数据库+系统+lw文档+mybatis+运行部署 java计算机毕业设计网上书店的设计与实现源码+数据库+系统+lw文档+mybatis+运行部署 本源 ...

  8. java计算机毕业设计网上书店的设计与实现源码+系统+数据库+lw文档

    java计算机毕业设计网上书店的设计与实现源码+系统+数据库+lw文档 java计算机毕业设计网上书店的设计与实现源码+系统+数据库+lw文档 本源码技术栈: 项目架构:B/S架构 开发语言:Java ...

  9. java邮件登录系统设计_基于Java web的邮件管理系统的设计与实现(含源文件).doc

    毕业设计诚信声明书 毕 业 设 计 中文题目 基于Java web的邮件管理系统的设计与实现 英文题目 Based on Java web email management system design ...

  10. java跳蚤市场源码,基于JAVA的校园网上跳蚤市场的设计与实现.doc

    本文阐述了校园网上跳蚤市场的设计与实现过程,并且详细介绍了系统的需求分析以及各部分功能的实现代码.系统的开发以Java语言为开发环境,以Eclipse软件为开发平台,以MySQL为后台数据库 ,主要实 ...

最新文章

  1. 制作Windows Mobile程序安装包
  2. 昆仑mcp文件是什么版本_昆仑健康保2.0升级版怎么样?有哪些优缺点?
  3. 全球及中国碳化硅 (SiC) 肖特基二极管行业竞争潜力与供应规划研究报告2022版
  4. centos8中一键安装Nginx
  5. 办公室心理学-九型人格导图
  6. 前端工程师面试题汇总
  7. 全球仅4人,刚毕业年薪201万元 !华为最高档“天才少年”回应...
  8. usr / bin / ld:找不到-l <nameOfTheLibrary>
  9. IOS开发人员必看的精品资料100
  10. ARCH与GARCH模型
  11. 同是共享内存,shm_open与shmget有什么差异?
  12. 惠普1000-1408TX拆机换硅脂,清灰
  13. 科林明伦杯 哈尔滨理工大学第十届程序设计竞赛 (补)
  14. android listview 资源回收,ListView的回收机制如何运作
  15. 管人就是管情绪——从《纸牌屋》中的心理操控说起
  16. 什么是Platform SDK?
  17. Mysql 与ES(Elastic Search)对比
  18. 单片机通信——spi、iic、uart
  19. 英语学习的方法(1)
  20. 问题 D: DD_BOND看到的hcy

热门文章

  1. Talib技术因子详解(十)
  2. uniapp 即时通讯_在uni-app使用极光IM 开发一个聊天室
  3. 飞行堡垒FX80GM热键无反应与触摸板无法使用
  4. tt按键精灵从入门到精通完整版
  5. 【机器学习数学基础】Mathematics for Machine Learning 梳理+习题答案
  6. pip下载opencv报错
  7. 【原创工具】蓝牙串口无线烧写STM32程序的工具,支持HC-05和CC2541两种蓝牙模块
  8. 一次HBase问题的解决过程(Status: INCONSISTENT)
  9. java 记账系统_案例分享用java开发实现一个记账系统(代码全)
  10. 学编程语言,记不住代码怎么办?