最近一直在学习web,下面通过所做的网上购物系统来整理一下最近所学的知识以及学习过程中遇到的问题还有自己的认识。
对于一个web项目,个人觉得数据库是必不可少的,所以第一步要做的就是设计并实现数据库,而这一块我们就要考虑要做的项目中都需要哪些内容,也就是数据库中应该包含哪些表,表里面应该有哪些属性,然后就要考虑这些表之间的关系。而我做的这个简单的网购系统目前只包含三个表-->
会员表 (标号(主键),用户名,密码,电子邮箱,手机号码)
订单表 (标号(主键)订单编号,选购日期,数量,支付金额,购买者,商品类型)
商品表 (标号(主键)商品号,商品名称,商品单价,生产日期)
这个项目我们也是以小组的形式做的,那么在设计好数据库之后就开始分工。首先呢就要把前台界面和后台功能分开,一个人负责写操作类,其他人负责写界面和servlet类。
下面分别介绍一下各部分的功能
1操作类:对于这个web项目,用户要做的就是在页面上点击一些按钮,然后我们会将其中的信息提交到项目中的web.xml文件中,通过页面中<form>表单中的action来查找,进而找到相应的servlet类进行处理,而servlet类主要就是调用我们所写的操作类,而操作类里面的内容主要就是对数据库的操作(增,删,改,查),但并不是通过一个操作类来对数据库进行所有的操作。一个数据库中会包含多个表,对于每个表我们都要有单独的一个Dao类对其操作,虽然里面的功能都是增、删、改、差,但不同的是我们可以根据传递不同的参数来得到不同的结果,而每个表对应一个Dao在后期管理和改善时会比较方便。
2页面:这部分相对来说会比较简单,因为它不涉及太多的逻辑部分,做页面的目的就是把它做得漂亮,能让用户眼前一亮就可以了。
3servlet类:前面也已经说过了,servlet类主要就是调用操作类。而它具体的流程就是页面首先将要提交的信息通过<form>表单提交到request中,通过web.xml文件映射到相应的servlet类,再通过servlet类中的service方法中的request参数获取提交过来的信息,再对操作类进行操作。
下面就回忆一下我们网购系统的开发过程,并讲诉一下开发过程中遇到的问题以及要注意的地方。
首先是项目的运行流程:

然后我们就要看看要做这么一个项目应该包含哪些包,哪些类。

这个是我们已经做好之后的项目。由于我在这个项目中参与的是对后台的操作,所以下面介绍的主要是后台的实现。
首先我根据数据库中所包含的表来创建pojo包中的成员类,类中的属性就是表中包含的属性,以用户表为例:
public class User { private int id; private String user_name; private String user_pwd; private String user_tel; private String user_email; private int user_limit; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getUser_limit() { return user_limit; } public void setUser_limit(int limit) { this.user_limit = limit; } public String getUser_name() { return user_name; } public void setUser_name(String user_name) { this.user_name = user_name; } public String getUser_pwd() { return user_pwd; } public void setUser_pwd(String user_pwd) { this.user_pwd = user_pwd; } public String getUser_tel() { return user_tel; } public void setUser_tel(String user_tel) { this.user_tel = user_tel; } public String getUser_email() { return user_email; } public void setUser_email(String user_email) { this.user_email = user_email; } }
成员类中只要设置属性的set和get方法就可以了,而成员类的作用就是在servlet中方便我们把在request中获取的信息封装起来,便于操作。
然后就是Dao这个包中的对应于每个成员的操作类,同样以用户的操作类为例:
import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import pojo.User; /** * 用户请求操作类 * * @author Administrator * */ public class UserDAO { private static java.sql.Connection conn;// 数据库接口 /** * 用户添加函数操作 * */ public static void addUser(User user) { // 获取数据库接口 conn = Connection.getConnection(); String sqladd = "insert into user(user_name,user_pwd,user_tel,user_email,user_limit) values(?,?,?,?,?);"; try { // 预编译 PreparedStatement pst = conn.prepareStatement(sqladd); pst.setString(1, user.getUser_name()); pst.setString(2, user.getUser_pwd()); pst.setString(3, user.getUser_tel()); pst.setString(4, user.getUser_email()); pst.setInt(5, user.getUser_limit()); // 执行数据库代码 pst.executeUpdate(); pst.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 用户删除函数 * * @param id * (只需要传入用户Id) */ public static void deleteUser(int id) throws Exception { // 获取数据库接口 conn = Connection.getConnection(); conn.setAutoCommit(false); String sqldelete = "delete from User where id =" + id; try { Statement stm = conn.createStatement(); stm.executeUpdate(sqldelete); // 提交结果 conn.commit(); } catch (Exception e) { e.printStackTrace(); } } /** * 用户更新函数 */ public static void updateUser(User user) { // 获取数据库接口 conn = Connection.getConnection(); String sqlupdate = "update user set user_name=?,user_pwd=?,user_email=?,user_tel=?,user_limit=? where id = " + user.getId() + ";"; try { // 预编译 PreparedStatement pst = conn.prepareStatement(sqlupdate); pst.setString(1, user.getUser_name()); pst.setString(2, user.getUser_pwd()); pst.setString(4, user.getUser_tel()); pst.setString(3, user.getUser_email()); pst.setInt(5, user.getUser_limit()); // 执行代码 pst.executeUpdate(); pst.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 查询函数(用于操作登陆操作或者查询作用) * * @param user */ public static User checkLogin(String userName, String userPwd) { // 获取数据库接口 conn = Connection.getConnection(); try { String sqlcheck = "select * from user where user_name=? and user_pwd=?"; PreparedStatement pst = conn.prepareStatement(sqlcheck); pst.setString(1, userName); pst.setString(2, userPwd); ResultSet rs = pst.executeQuery(); if (rs.next()) { // 如果数据库中有此用户,则返回此用户 User user = new User(); user.setId(rs.getInt(1)); user.setUser_name(rs.getString(2)); user.setUser_pwd(rs.getString(3)); user.setUser_tel(rs.getString(4)); user.setUser_email(rs.getString(5)); user.setUser_limit(rs.getInt(6)); return user; } } catch (Exception e) { e.printStackTrace(); } // 若返回为空 则查询不到此用户 return null; } /** * 注册时检测该用户名是否已经被使用 * * @param userName * @return */ public static boolean checkUser(String userName) { // 得到连接对象 conn = Connection.getConnection(); String sql = "select * from User where User_name = ?"; try { PreparedStatement pst = conn.prepareStatement(sql); pst.setString(1, userName); ResultSet rs = pst.executeQuery(); return rs.next(); } catch (SQLException e) { e.printStackTrace(); } return false; } public static List<User> getUserList() { List<User> userList = new ArrayList<User>(); // 获取数据库接口 conn = Connection.getConnection(); try { String sqlcheck = "select * from user"; PreparedStatement pst = conn.prepareStatement(sqlcheck); ResultSet rs = pst.executeQuery(); while (rs.next()) { // 如果数据库中有此用户,则返回此用户 User user = new User(); user.setId(rs.getInt(1)); user.setUser_name(rs.getString(2)); user.setUser_pwd(rs.getString(3)); user.setUser_email(rs.getString(4)); user.setUser_tel(rs.getString(5)); user.setUser_limit(rs.getInt(6)); userList.add(user); } return userList; } catch (Exception e) { e.printStackTrace(); } // 若返回为空 则查询不到此用户 return null; } }
这个用户的操作类中有添加用户(需传入User对象),删除用户(根据用户id删除),更新用户(传入User对象),查找用户(根据用户名和密码查找),检测用户名是否已经被使用的方法(传入用户名),返回所有用户的列表方法。
接下来就是在servlet类中处理请求并调用dao类了。页面提交过来的信息是通过web.xml这个文件来找到对应的servlet类的,主要就是通过里面的<servlet>和<servlet-mapping>这两个标签来映射到servlet类的。
<servlet>
<servlet-name>名称(随意起)</servlet-name>
<servlet-class>包名.要映射的servlet类名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>名称(随意起,但要和上面的名字一样)</servlet-name>
<url-pattern>提交过来的地址</url-pattern>
</servlet-mapping>
通过这两个标签就可以将页面上的信息提交到我们自己写的servlet类中,下面通过登录过程来展示一下整个的流程。
首先是登录界面(.jsp)
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript"> function checkLogin() { var name = document.getElementById("user_name").value; var pwd = document.getElementById("user_pwd").value; if (name == "") { alert("用户名不能为空!"); return false; } else if (pwd == "") { alert("密码不能为空!"); return false; } return true; } </script> <title>网上购物</title> </head> <body> <center> <form action="homepage/login"> <h1 align="center">网上购物系统登录</h1> <p align="center"> 用户名:<input type="text" name="user_name" id="user_name" /> </p> <p align="center"> 密码:<input type="password" name="user_pwd" id="user_pwd" /> </p> <a href=""><input type="submit" value="登陆" onclick="return checkLogin();" /></a> <a href="register.jsp">注册</a> </form> </center> </body> </html>
当点击登录时该页面会将用户名和密码提交到homepage/login这个地址上,然后就会在web.xml中查找这个地址,然后映射到对应的servlet类中。其中web.xml中的配置是:
<servlet> <servlet-name>login</servlet-name> <servlet-class>Servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/homepage/login</url-pattern> </servlet-mapping>
所以它会跳到Servlet包下面的LoginServlet类中,而LoginServlet类的主要内容是:
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import pojo.Goods; import pojo.User; import Dao.GoodsDAO; import Dao.UserDAO; public class LoginServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) { try { request.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=UTF-8"); // 获取用户名和密码 String user_name = request.getParameter("user_name"); String user_pwd = request.getParameter("user_pwd"); // 检测数据库中是否存有该用户 User user = UserDAO.checkLogin(user_name, user_pwd); if (user != null && user.getUser_limit() == 0) { // 判断登陆者为用户 request.getSession().setAttribute("user", user); Goods goods = GoodsDAO.checkGood(1); System.out.println("login->购买前商品数量:" + goods.getGoods_count()); // 将商品列表存到session中 request.getSession().setAttribute("goods", goods); // 如果存有该用户则登陆成功,跳转到主商品界面 request.getRequestDispatcher("main.jsp").forward(request, response); } else if (user != null && user.getUser_limit() == 1) { // 管理员登陆 // 进入管理员界面 request.getRequestDispatcher("../admit/admit_main.jsp") .forward(request, response); } else { // 登陆失败 System.out.println("shibai"); request.setAttribute("error", "<span style='color:#cc0000'>登陆失败!</span>"); request.getRequestDispatcher("../error.jsp").forward(request, response); } } catch (Exception e) { e.printStackTrace(); } } /** * 初始化商品 * * @return */ public Goods initGoods() { Goods goods = new Goods(); goods.setGoods_id(1); goods.setId(1); goods.setGoods_count(200); goods.setGoods_date("2013/4/9"); goods.setGoods_name("ipad"); goods.setGoods_price(4000); goods.setType_name("电子"); return goods; } }
这个类的作用就是先获取到request中传来的用户名和密码,然后到数据库中检测是否含有该用户,如果有的话再进行判断登陆者是用户还是管理员,用户的话就会进入商品界面,管理员就会进入管理界面。
这样登陆的过程就基本实现了,其他的servlet也基本是这样,都是获取信息,然后调用Dao方法完成对数据库的操作。
下面主要说一下我们遇到的问题:
1在做这个项目之前我们已经把大致的流程想好了,所以开发速度还是比较快的,但遇到最烦的问题就是页面的路径问题。尤其是当我们的界面过多的时候就会出现在web.xml中找不到对应的url地址,所以现在看到网页上出现404就不想理它了。而解决这个问题的办法我个人的理解就是可以多分文件夹,但尽量避免文件夹的嵌套。就是说可以在广度上延伸,但不要在深度上延伸。当然如果你觉得你有好方法来解决路径问题你可以在深度上延伸,但对于我这种路径一长就乱了的人来说,只有一个文件夹是最好的。
2 传递信息问题。最开始为了方便,只要用户登录成功,我们就把所有的信息都放到session中保管,之所以放到session中保管而不是在request中是因为它们的作用域不同,session是在整个的对话过程中都存在,而request只是在一次请求应答中,所以为了只要存放一次信息以后都不用管它们了就放到session中保管了,虽然这样方便,但也有一些缺点,那就是session的存放空间是有限的,如果存放的无用数据过多会在后面出现数据存放不下的情况。那么解决这个问题的方法就是把信息存到request中,这样在一次请求之后request就会自动消失,不会占用大量的空间。并且不要一次性把所有的信息都存起来,我们要根据当前所得到的信息来判断他需要哪些数据,一次只存放它需要的东西。
感受:
分工不明确:在做之前我们觉得每个人负责一个部分很好,这样每个人在编写的时候就不需要关心其他人的工作进度,最后只要把每个人做的整合到一起就好了,但后来发现这样做有一点不好,因为做完一个项目之后每个人只对他负责的那部分有了解,而对项目其他部分的了解就有些不足,那这样的分工显然是不合理的,完成一个项目之后我们不能只了解自己负责的部分,应该是对项目的整个流程都有了解,那分工的时候就不能按模块分工,而要按功能分工,这样每个人就会对项目的整体流程有所了解了。
相关推荐
### Web的安全防御浅谈 随着互联网的飞速发展,Web应用已经成为企业和个人不可或缺的一部分,但同时也面临着各种安全威胁。为了确保Web应用的安全性,开发者必须从设计之初就将安全因素考虑进去。本文将从几个关键...
Python是一种高级编程语言,以其简洁明了的语法和强大的功能深受程序员喜爱,...继续深入学习,你会发现Python的强大之处,包括数据处理、网络编程、科学计算、Web开发等众多领域。祝你在Python的学习之旅中取得成功!
对于初入行业的学生或转型中的从业者,可以从基础的网页制作开始,逐步提升技能。例如,可以先学习基础的HTML和CSS,理解网页的基本构造和样式规则,然后深入JavaScript和相关框架,掌握动态网页的实现。同时,了解...
Struts2之ajax初析的并结合jquery一个例子 Web2.0的随波逐流,Ajax那是大放异彩,Struts2框架自己整合了对Ajax的原生支持(struts 2.1.7+,之前的版本可以通过插件实现),框架的整合只是使得JSON的创建变得异常简单...
1. jQuery简介:jQuery是一个继prototype之后的优秀JavaScript框架,由John Resig创建于2006年初。它简化了JavaScript以及Ajax编程,以“write less, do more”为宗旨,用更少的代码做更多的事情。jQuery像Ruby一样...
浅谈Java技术对互联网时代的重要作用 Java技术是互联网时代不可或缺的一部分,自从1996年初Sun公司发布第一个Java开发工具以来,Java语言就成为了跨平台的、面向对象的编程语言。Java语言的优良特性,如可移植性、...
的确,初接触.NET Remoting的人多半会有这样的疑问,因为大部分的文章和书籍在介绍.NET Remoting时都只介绍了通道,对象,激活和生存周期等等概念,在谈到如何进行远程通信的时候,都只告诉读者如何从客户端激活一个...
它的诞生源自1990年代初,芬兰程序员Linus Torvalds为创建一个与Minix兼容的开放源码系统而努力,最终在1991年推出了首个Linux内核版本。Linux的发展受益于其开源特性,吸引了众多国际知名企业的支持,如IBM、Intel...
它的出现源于21世纪初Web2.0时代的爆发,特别是大型在线服务如Google的快速发展,推动了分布式计算、并行计算和虚拟化等技术的融合,形成了如今的云计算基础。 在电力系统中,云技术的应用主要体现在以下几个方面:...
在放假之初,我抽时间看了《白帽子讲web安全》,吴翰清基本上把web安全中所有能够遇到的问题、解决思路归纳总结得很清晰,也是我这一次整体代码安全性的基石。 我希望能分如下几个方面来分享自己的经验 把握整站的...
JavaScript,简称JS,是Web开发中的关键组成部分,主要用于前端交互逻辑和动态效果的实现。学习JavaScript需要明确其定位,它是负责操纵和调整DOM(文档对象模型),以改变网页内容和行为的核心技术。以下是一些循序...
其概念源于20世纪60年代初美国等西方发达国家。我国专家在第一次全国办公自动化规划讨论会上提出办公自动化的定义为:利用先进的科学技术,使部分办公业务活动物化于人以外的各种现代化办公设备中,由人与技术设备...
SSRS不仅为报表制作人员、数据分析人员和决策者提供所需的信息,而且设计之初就考虑到了与下一代数据库产品YUKON的集成。产品具有三大核心功能:报表设计/定制、报表管理和报表发布,构成了报表的生命周期。SSRS支持...
当互联网初代第一次用邮箱、用OICQ&、用搜索的时候感觉到了前无所有的便捷,这样的产品才是有生命力的,元宇宙和Web3的问题就在于他们的概念很大但是他们只存在云圈子里面,普通人并不会关心概念,你并不会因为去...
web应用程序的安全性算是一个老生常谈的问题了,当然asp.net mvc也不例外,虽然他在设计之初就对此有了一些防范,但是还是要差很多,有很多地方需要我们程序猿们注意的地方,我们今天就来简单的探讨下
4 初入 Odoo 17 4.1 管理数据库 17 4.2 登录界面 18 4.3 Administrator 首选项 19 4.4 导入一个翻译 20 4.5 新的 Demo 用户 20 4.6 模块管理 21 4.7 修改公司信息 21 4.8 打开技术特性支持之后 22 4.9 进销存和财务...
本月初,这家初创公司发布了其设计领域的首项技术,而Aria Behrozian在现场发布会上谈到了该软件,并分享了对该软件的总体看法。 根据制造商的说法,该软件是为帮助设计而制作的。 使用该软件的方式是,在软件开发...
7. **J2SE学习笔记(7)初谈通信.DOC**:可能是关于网络通信的初步介绍,包括Socket编程,或者是HTTP客户端/服务器实现。 8. **J2SE学习笔记(7)多线程.DOC**:多线程是并发编程的关键,这部分可能会讲解线程的...
在掌握基础知识和应用开发技术之后,书中进一步引入了数据库通信、Oracle高级队列、作业管理、大型对象以及开发Web程序等高级主题。此外,还特别强调了性能优化技巧,这对于解决实际开发中遇到的性能瓶颈有着重要的...
### 从核心理念谈起 LightBound-开源的核心理念在于简化前端与后端之间的交互,避免复杂的自定义标签和文件结构。这为开发者创造了更为简洁和直观的开发体验。传统Web框架往往要求开发者深入学习一套复杂的模板语言...