Web 应用开发课程设计——注册页面
1 需求分析
设计一个注册页面,手机验证码发送,将注册的用户信息放入数据库中。
1.1 用户注册
当程序运行时,显示注册所需要填写的个人信息。
个人信息有用户名、密码、Email、姓名、手机号、性别、出生日期。
1.2 邮箱激活
注册成功后,跳转邮箱激活页面。
1.3 主菜单
运行 Tomcat,进入系统主界面,如下:
1.3 各项功能
1 表单校验
1).用户名:单词字符,长度 8 到 20 位 2).密码:单词字符,长度 8 到 20 位 3).email:邮件格式 4).姓名:非空 5).手机号:手机号格式 6).出生日期:非空 7).验证码:非空
2. 注册成功
2.1 输入信息注册:
2.2 注册成功跳转页面
2 系统设计
2.1 数据库表
图 2.1.1 数据库表
图 2.1.2 数据库表
2.2 ER 图
图 3-1 数据库 ER 图
2.3 UML 类图(Class Diagram)
对于用户功能模块,共设计如下 5 个类。
VO 实体类 User:与数据库结构进行映射的类。主要由属性,setter, getter 方法组成,VO 类中的属性与表中的字段相对应,每一个 VO 类的对象都表示表中的每一条记录
DAO 接口 IUserDAO:主要定义操作的接口,定义一系列数据库的原子性操作,例如增删改查(通常称为 CRUD)等。
DAO 实现类 UserDAOImpl:DAO 接口的真实实现类,主要完成具体数据库操作,但不负责数据库的打开和关闭。
DAO 工厂类 DAOFactory:通过工厂类取得一个 DAO 的实例化对象
业务逻辑实现类 UserService:对于数据层的原子操作进行整合。还要负责数据库的打开与关闭(不管是否出异常,数据库都要关闭)
各类的结构及类之间的关系如图 2-5 所示:
图 2-3 用户功能类图
2.4 UML 时序图(Sequence Diagram)
2.4.1 系统注册
图 2.4.1
3 系统实现
3.1 项目结构
图 3.1 项目结构
3.2 配置文件
在项目下新建 Source Folder,名为 resources
3.2.1 druid.properties 文件
该配置文件主要是以文件形式保存数据库的驱动类名称,连接数据库的 URL 地址,访问数据库的用户名及对应的密码,程序运行时会读取该文件相关信息,避免硬编码,当相关信息发生变化时,只需修改配置文件而不用修改源代码,增加程序的可扩展型。
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web_kechengsheji
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
3.2.2 web.xml 文件
web.xml 文件是用来初始化配置信息
```
3.3 VO 类 User.java
3.3.1User 的实体类
``` package vo;
import java.io.Serializable;
/* * 用户实体类 / public class User implements Serializable { private int uid;//用户id private String username;//用户名,账号 private String password;//密码 private String name;//真实姓名 private String birthday;//出生日期 private String sex;//男或女 private String telephone;//手机号 private String email;//邮箱 private String status;//激活状态,Y代表激活,N代表未激活 private String code;//激活码(要求唯一)
/* * 无参构造方法 / public User() { }
/* * 有参构方法 * @param uid * @param username * @param password * @param name * @param birthday * @param sex * @param telephone * @param email * @param status * @param code / public User(int uid, String username, String password, String name, String birthday, String sex, String telephone, String email, String status, String code) { this.uid = uid; this.username = username; this.password = password; this.name = name; this.birthday = birthday; this.sex = sex; this.telephone = telephone; this.email = email; this.status = status; this.code = code; }
public int getUid() { return uid; }
public void setUid(int uid) { this.uid = uid; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBirthday() { return birthday; }
public void setBirthday(String birthday) { this.birthday = birthday; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
public String getTelephone() { return telephone; }
public void setTelephone(String telephone) { this.telephone = telephone; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getCode() { return code; }
public void setCode(String code) { this.code = code; } } ```
3.3.2ResultInfo 的实体类
用于封装后端返回前端数据对象
``` package vo;
import java.io.Serializable; import java.util.Objects;
/* * 用于封装后端返回前端数据对象 / public class ResultInfo implements Serializable { private boolean flag;//后端返回结果正常为true,发生异常返回false private Object data;//后端返回结果数据对象 private String errorMsg;//发生异常的错误消息
//无参构造方法 public ResultInfo() { } public ResultInfo(boolean flag) { this.flag = flag; } / * 有参构造方法 * @param flag * @param errorMsg */ public ResultInfo(boolean flag, String errorMsg) { this.flag = flag; this.errorMsg = errorMsg; } / * 有参构造方法 * @param flag * @param data * @param errorMsg */ public ResultInfo(boolean flag, Object data, String errorMsg) { this.flag = flag; this.data = data; this.errorMsg = errorMsg; }
public boolean isFlag() { return flag; }
public void setFlag(boolean flag) { this.flag = flag; }
public Object getData() { return data; }
public void setData(Object data) { this.data = data; }
public String getErrorMsg() { return errorMsg; }
public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } }
```
3.4 接口类 UserDAO.java
实现对数据库 t_user 表中的增删查改
``` package dao;
import vo.User;
public interface UserDao {
/* * 根据用户名查询用户信息 * @param username * @return / public User findByUsername(String username);
/* * 用户保存 * @param user / public void save(User user);
User findByCode(String code);
void updateStatus(User user);
User findByUsernameAndPassword(String username, String password); }
```
3.6 工具包 Util
3.6.1 JDBCUtils .java
实现数据库的连接和释放
``` package 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.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;
/ 1. 声明静态数据源成员变量 2. 创建连接池对象 3. 定义公有的得到数据源的方法 4. 定义得到连接对象的方法 5. 定义关闭资源的方法 / public class JDBCUtils { // 1. 声明静态数据源成员变量 private static DataSource ds;
// 2. 创建连接池对象 static { // 加载配置文件中的数据 InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"); Properties pp = new Properties(); try { pp.load(is); // 创建连接池,使用配置文件中的参数 ds = DruidDataSourceFactory.createDataSource(pp); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }
// 3. 定义公有的得到数据源的方法 public static DataSource getDataSource() { return ds; }
// 4. 定义得到连接对象的方法 public static Connection getConnection() throws SQLException { return ds.getConnection(); }
// 5.定义关闭资源的方法 public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) {} }
if (stmt != null) { try { stmt.close(); } catch (SQLException e) {} }
if (conn != null) { try { conn.close(); } catch (SQLException e) {} } }
// 6.重载关闭方法 public static void close(Connection conn, Statement stmt) { close(conn, stmt, null); } } ```
3.6.2 MailUtils.java
发送邮件的工具类
``` package utils;
import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Properties;
/ * 发邮件工具类 / / 这个工具类测试有问题 好像是javamail更新用不了 */ public final class MailUtils { private static final String USER = "12295427494@qq.com"; // 发件人称号,同邮箱地址 private static final String PASSWORD = "uamvpeeapvpmifii"; // 如果是qq邮箱可以使户端授权码,或者登录密码
/ * * @param to 收件人邮箱 * @param text 邮件正文 * @param title 标题 / / 发送验证信息的邮件 */ public static boolean sendMail(String to, String text, String title){ try { final Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.host", "smtp.qq.com");
// 发件人的账号 props.put("mail.user", USER); //发件人的密码 props.put("mail.password", PASSWORD);
// 构建授权信息,用于进行SMTP进行身份验证 Authenticator authenticator = new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { // 用户名、密码 String userName = props.getProperty("mail.user"); String password = props.getProperty("mail.password"); return new PasswordAuthentication(userName, password); } }; // 使用环境属性和授权信息,创建邮件会话 Session mailSession = Session.getInstance(props, authenticator); // 创建邮件消息 MimeMessage message = new MimeMessage(mailSession); // 设置发件人 String username = props.getProperty("mail.user"); InternetAddress form = new InternetAddress(username); message.setFrom(form);
// 设置收件人 InternetAddress toAddress = new InternetAddress(to); message.setRecipient(Message.RecipientType.TO, toAddress);
// 设置邮件标题 message.setSubject(title);
// 设置邮件的内容体 message.setContent(text, "text/html;charset=UTF-8"); // 发送邮件 Transport.send(message); return true; }catch (Exception e){ e.printStackTrace(); } return false; }
public static void main(String[] args) throws Exception { // 做测试用 MailUtils.sendMail("2073889802@qq.com","你好,这是一封测试邮件,无需回复。","测试邮件"); System.out.println("successful"); }
} ```
3.6.3 MailUtils.java
产生 UUID 随机字符串工具类(用于验证邮箱的激活)
``` package utils;
import java.util.UUID;
/ * 产生UUID随机字符串工具类 */ public final class UuidUtil { private UuidUtil(){} public static String getUuid(){ return UUID.randomUUID().toString().replace("-",""); } / * 测试 */ public static void main(String[] args) { System.out.println(UuidUtil.getUuid()); System.out.println(UuidUtil.getUuid()); System.out.println(UuidUtil.getUuid()); System.out.println(UuidUtil.getUuid()); } } ```
3.7 服务层(实现类)UserServiceImpl.java
``` package service.impl;
import dao.UserDao; import dao.impl.UserDaoImpl; import service.UserService; import utils.MailUtils; import utils.UuidUtil; import vo.User;
public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoImpl(); /* * 注册用户 * @param user * @return /
public boolean register(User user) { //1.根据用户名查询用户对象 User u = userDao.findByUsername(user.getUsername()); //判断u是否为null if(u != null){ //用户名存在,注册失败 return false; } //2.保存用户信息 //2.1设置激活码,唯一字符串 user.setCode(UuidUtil.getUuid()); //2.2设置激活状态 user.setStatus("N"); userDao.save(user);
//3.激活邮件发送,邮件正文?
String content="注册邮箱注册邮箱 作者:李悦"+user.getCode();
MailUtils.sendMail(user.getEmail(),content,"激活邮件");
return true; }
/* * 激活用户 * @param code * @return /
public boolean active(String code) { //1.根据激活码查询用户对象 User user = userDao.findByCode(code); if(user != null){ //2.调用dao的修改激活状态的方法 userDao.updateStatus(user); return true; }else{ return false; } } } ```
4 系统测试
4.1 注册成功
4.1.1 填写信息(这里以我个人信息为例)
4.1.2 注册成功跳转页面
4.1.3 刷新数据库中表的信息
4.1.4 多次注册后刷新数据库中表的信息
4.2 注册失败
4.2.1 主键重复(用户名)
4.2.2 邮件格式错误(Email 方框变红)
4.2.3 密码或用户名不合规范
4.2.4 验证码错误
5 系统总结
1.自己在完成这个功能的时候,比较偏向于后端,前端的样式和布局有参考之前写过的项目。
- 最初设计是使用手机验证码进行注册,去网上查找 API 的时候,查到了一个免费有保证的 api,但我的申请被驳回了。将手机验证改成了邮箱验证,因为 javaMail 中封装好了,邮箱验证,在网上查找资料,找到相应的工具类,注册这一步要轻松很多。
- 但是我在进行邮件发送测试的时候系统出现了以下报错
查看我相应测试类的代码
程序是没有问题的,能够输出 successful
后来上网查找博客
是设置部分的授权码没有开启,我将三个授权码都开启后重新运行测试类,发现报错并没有解决
原因是:javamail 第三方发送版本太低了,现在网易和 QQ 邮箱,第三方授权安全性很高,无法正常发送。
个人感悟:我的前端部分基础不牢固,写 AJAX 请求的时候,需要套着之前的项目模板进行写。但是经过很长一段时间的练习,我后端部分的基础还是很牢固的,这是我值得欣慰的。
我给自己的评价是优,因为通过这门课,我有真的学到一些东西,从最初的不理解的三层架构,到后面可以把后端基础写的很熟练。但很遗憾的是,我还是没有很熟练的掌握 SSM 框架,但是框架是建立基础上的,我的打算是寒假一直到开学尽量把三大框架掌握牢固,好为后面的实习和毕业设计做准备。
我最初写的题是第二题,但是我第二题的功能没有完全实现,但是我想多做一点,做好一点,于是把注册这个题也写了,注册这个题很简单,第二题对 AJAX 请求的要求部分比较高,但是查查文档也能写出来。
参考文献
- 基于JSP的校园网站的设计与实现(吉林大学·张帆)
- 基于MVC模式的水利服务平台系统的设计与实现(中山大学·罗晴文)
- 艺术院校《网页设计》网络课程的设计与开发(山东师范大学·邹杰)
- 基于J2EE的高职院校课程网络教学平台的研究与设计(电子科技大学·刘鲁平)
- 项目课程设计与应用研究——以《网站设计与开发》课程为例(西北师范大学·李平)
- ASP/JSP技术及WEB应用系统研究开发(西安理工大学·薛梅)
- 项目课程设计与应用研究——以《网站设计与开发》课程为例(西北师范大学·李平)
- 达州职业技术学院网上考试系统的设计与实现(电子科技大学·谷潇)
- 达州职业技术学院网上考试系统的设计与实现(电子科技大学·谷潇)
- 艺术院校《网页设计》网络课程的设计与开发(山东师范大学·邹杰)
- 计算机基础系列课程网络CAI教学的研究与实践——现代远程教学系统基于Web的辅助教学平台(成都理工大学·袁爱新)
- 艺术院校《网页设计》网络课程的设计与开发(山东师范大学·邹杰)
- 基于WEB的网络教学系统的设计与实现(东北大学·周海斌)
- 基于J2EE的Web组件开发平台的研究与实现(浙江大学·周明明)
- 基于B/S结构的学校管理信息系统的研究与开发(四川大学·徐永红)
本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设港湾 ,原文地址:https://bishedaima.com/yuanma/35922.html