当前位置:网站首页>1、项目第二阶段——用户注册和登陆
1、项目第二阶段——用户注册和登陆
2022-06-25 03:54:00 【@JiaHao】
第二阶段——用户注册和登陆
1、JavaEE项目的三层架构

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
web 层 com.my.book.web/servlet/controller
service 层 com.my.book.service Service接口包
com.my.book.service.impl Service 接口实现类
dao 持久层 com.my.book.dao Dao 接口包
com.my.book.dao.impl Dao 接口实现类
实体 bean 对象 com.my.book.pojo/entity/domain/bean JavaBean 类
测试包 com.my.book.test/junit
工具类 com.my.book.util
搭建书城项目开发环境:

2、先创建书城需要的数据库和表。
数据库
drop database if exists book;
create database book;
use book;
create table t_user(
id int primary key auto_increment,
username varchar(20) not null unique,
password varchar(32) not null,
email varchar(200)
);
insert into t_user(username,password,email) values(admin,123,[email protected]);
select * from t_user;

3、编写数据库表对应的 JavaBean 对象
public class User {
private Integer id;
private String username;
private String password;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User(Integer id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public User() {
}
}
4、编写工具类 JdbcUtils
4.1、导入需要的 jar 包(数据库和连接池需要):

4.2、在 src 源码目录下编写 jdbc.properties 属性配置文件:
username=root
password=root
url=jdbc:mysql://localhost:3306/book
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10
4.3、编写 JdbcUtils工具类:
public class JdbcUtils {
private static DruidDataSource dataSource;
static {
try {
Properties properties = new Properties();
// 读取 jdbc.properties 属性配置文件
InputStream inputStream =
JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
// 从流中加载数据
properties.load(inputStream);
// 创建 数据库连接 池
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接池中的连接
* 如果返回 null,说明获取连接失败<br/>有值就是获取连接成功
*/
public static Connection getConnection(){
Connection conn = null;
try {
conn = dataSource.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭连接,放回数据库连接池
* @param conn
*/
public static void close(Connection conn){
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
4.4、JdbcUtils 测试
public class JdbcUtilsTest {
@Test
public void testJdbcUtils(){
for (int i = 0; i < 100; i++){
Connection connection = JdbcUtils.getConnection();
System.out.println(connection);
JdbcUtils.close(connection);//记得使用后要关闭
}
}
}

这样表示连接成功
5、编写 BaseDao
5.1、导包
使用前记得导DBUtils 的jar包
5.2、编写 BaseDao:
public abstract class BaseDao {
//使用DbUtils操作数据库
private QueryRunner queryRunner = new QueryRunner();
/**
* update() 方法用来执行:Insert\Update\Delete语句
*
* @return 如果返回-1,说明执行失败返回其他表示影响的行数
*/
public int update(String sql, Object... args) {
Connection connection = JdbcUtils.getConnection();
try {
return queryRunner.update(connection, sql, args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(connection);
}
return -1;
}
/**
* 查询返回一个javaBean的sql语句
*
* @param type 返回的对象类型
* @param sql 执行的sql语句
* @param args sql对应的参数值
* @param <T> 返回的类型的泛型
* @return
*/
public <T> T queryForOne(Class<T> type, String sql, Object... args) {
Connection con = JdbcUtils.getConnection();
try {
return queryRunner.query(con, sql, new BeanHandler<T>(type), args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(con);//关闭流
}
return null;
}
/**
* 查询返回多个javaBean的sql语句
*
* @param type 返回的对象类型
* @param sql 执行的sql语句
* @param args sql对应的参数值
* @param <T> 返回的类型的泛型
* @return
*/
public <T> List<T> queryForList(Class<T> type, String sql, Object... args) {
Connection con = JdbcUtils.getConnection();
try {
return queryRunner.query(con, sql, new BeanListHandler<T>(type), args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(con);
}
return null;
}
/**
* 执行返回一行一列的sql语句
* @param sql 执行的sql语句
* @param args sql对应的参数值
* @return
*/
public Object queryForSingleValue(String sql, Object... args){
Connection conn = JdbcUtils.getConnection();
try {
return queryRunner.query(conn, sql, new ScalarHandler(), args);
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.close(conn);
}
return null;
}
6、编写 UserDao 和测试
6.1、UserDao 接口:
public interface UserDao {
/**
* 根据用户名查询用户信息
* @param username 用户名
* @return 如果返回null,说明没有这个用户。反之亦然
*/
public User queryUserByUsername(String username);
/**
* 根据 用户名和密码查询用户信息
* @param username
* @param password
* @return 如果返回null,说明用户名或密码错误,反之亦然
*/
public User queryUserByUsernameAndPassword(String username,String password);
/**
* 保存用户信息
* @param user
* @return 返回-1表示操作失败,其他是sql语句影响的行数
*/
public int saveUser(User user);
}
6.2、UserDaoImpl 实现类
public class UserDaoImpl extends BaseDao implements UserDao {
//查询根据username
@Override
public User queryUserByUsername(String username) {
String sql = "select username,password,email from t_user where username = ?";
return queryForOne(User.class, sql, username);
}
@Override
public User queryUserByUsernameAndPassword(String username, String password) {
String sql = "select id,username,password,email from t_user where username = ? and password = ?";
return queryForOne(User.class, sql, username,password);
}
//保存数据
@Override
public int saveUser(User user) {
String sql = "insert into t_user(username,password,email) values(?,?,?)";
return update(sql, user.getUsername(),user.getPassword(),user.getEmail());
}
}
6.3UserDao 测试:
public class UserDaoTest {
UserDao userDao=new UserDaoImpl();
@Test
public void queryUserByUsername() {
if(userDao.queryUserByUsername("admin")==null){
System.out.println("用户可用!");
}else{
System.out.println("用户已存在");
}
}
@Test
public void saveUser() {
System.out.println();
}
@Test
public void queryUserByUsernameAndPassword() {
if(userDao.queryUserByUsernameAndPassword("admin","123")==null){
System.out.println("用户密码错误,登录失败");
}else{
System.out.println("查询成功");
}
}
7、编写 UserService 和测
7.1UserService 接口
public interface UserService {
//注册用户
public void registUser(User user);
//登录
public User login(User user);
//检查用户是否可用
//true表示用户名存在
public boolean existsUsername(String username);
}
7.2、UserServiceImpl 实现类:
public class UserServiceImpl implements UserService{
UserDao userDao=new UserDaoImpl();
@Override
public void registUser(User user) {
userDao.saveUser(user);
}
@Override
public User login(User user) {
return userDao.queryUserByUsernameAndPassword(user.getUsername(),user.getPassword());
}
@Override
public boolean existsUsername(String username) {
if (userDao.queryUserByUsername(username)==null) {
//等于null说明没有查到,反之
return false;
}
return true;
}
}
7.3、UserService 测试:
public class UserServiceTest {
UserService userService=new UserServiceImpl();
@Test
public void registUser() {
userService.registUser(new User(null,"pjh","666","[email protected]"));
userService.registUser(new User(null,"zjt","555","[email protected]"));
}
@Test
public void login() {
System.out.println(userService.login(new User(null,"pjh","666","[email protected]")));
}
@Test
public void existsUsername() {
if (userService.existsUsername("pjh168")) {
System.out.println("用户名已存在!");
} else {
System.out.println("用户名可用!");
}
}
8、编写 web 层
8.1、实现用户注册的功能
8.1.1、图解用户注册的流程:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3qk9sxKp-1655786599875)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/923c4af974284258b04bfde5f0bb7bb5~tplv-k3u1fbpfcp-watermark.image?)]](/img/3a/8787dd84261d8f47095f7b72c58947.png)
8.1.2、修改 regist.html 和 regist_success.html 页
1、添加 base 标
<!--写 base 标签,永远固定相对路径跳转的结果-->
<base href="http://localhost:8080/book/">
2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>
3、修改注册表单的提交地址和请求方式

8.1.3、编写 RegistServlet 程序
public class RegistServlet extends HttpServlet {
private UserService userService=new UserServiceImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
//要求验证码为ABCD
if("abcd".equalsIgnoreCase(code)){
//正确
//检查用户名是否可用
if(userService.existsUsername(username)){
//不可用
System.out.println("用户名["+username+"]已存在");
// 跳回注册页面
req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
}else{
//可用,调用service保存到数据库
userService.registUser(new User(null,username,password,email));
// 跳转到注册成功register——success。html
req.getRequestDispatcher("/pages/user/regist_success.html").forward(req,resp);
}
}else{
//跳回注册页面
System.out.println("验证码["+code+"]错误");
req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
}
}
}
8.2、IDEA 中 Debug 调试的使
8.2.1、Debug 调试代码,首先需要两个元素:断点 + Debug 启动服务器
1、断点,只需要在代码需要停的行的左边上单击,就可以添加和取消
2、Debug 启动 Tomcat
8.2.2、测试工具栏:

8.2.3、其他常用调试相关按钮:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmvlwHn4-1655786599880)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/90cbef1cc21440d298e409ba1d5e4beb~tplv-k3u1fbpfcp-watermark.image?)]
8.3、用户登录功能的实现:
8.3.1、图解用户登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1WrD7Rn-1655786599882)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f59a48a310d8419ba6f25d47783f2c3c~tplv-k3u1fbpfcp-watermark.image?)]
8.3.2、修改 login.html 页面和 login_success.html 页面
1、添加 base 标
<!--写 base 标签,永远固定相对路径跳转的结果-->
<base href="http://localhost:8080/book/">
2修改 login.html 表单的提交地址和请求方式

8.3.3、LoginServlet 程序
public class LoginServlet extends HttpServlet {
private UserService userService = new UserServiceImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
// 调用 userService.login()登录处理业务
User loginUser = userService.login(new User(null, username, password, null));
// 如果等于null,说明登录 失败!
if (loginUser == null) {
// 跳回登录页面
req.getRequestDispatcher("/pages/user/login.html").forward(req, resp);
} else {
// 登录 成功
//跳到成功页面login_success.html
req.getRequestDispatcher("/pages/user/login_success.html").forward(req, resp);
}
}
}
总结
2.项目阶段二:用户注册和登陆的实现。
需求 1:用户注册
需求如下:
1)访问注册页面
2)填写注册信息,提交给服务器
3)服务器应该保存用户
4)当用户已经存在----提示用户注册 失败,用户名已存在
5)当用户不存在-----注册成功
需求 2:用户登陆
需求如下:
1)访问登陆页面
2)填写用户名密码后提交
3)服务器判断用户是否存在
4)如果登陆失败 —>>>> 返回用户名或者密码错误信息
5)如果登录成功 —>>>>
边栏推荐
- 墨天轮访谈 | IvorySQL王志斌—IvorySQL,一个基于PostgreSQL的兼容Oracle的开源数据库
- JS tool function, self encapsulating a throttling function
- DAP data scheduling function improvement description
- (超详细onenet TCP协议接入)arduino+esp8266-01s接入物联网平台,上传实时采集数据/TCP透传(以及lua脚本如何获取和编写
- Although the Internet in the traditional sense has long ceased to exist, this does not mean that the Internet has long disappeared
- Create SQLite table with shell script and add SQL statement -- General
- 【Proteus仿真】Arduino UNO按键控制数码管闪烁增/减显示
- Teach you how to install win11 system in winpe
- Development of trading system (XII) - Official quickfix document
- [harmony OS] [arkui] ETS development graphics and animation drawing
猜你喜欢

Hot and cold, sweet and sour, want to achieve success? Dengkang oral, the parent company of lengsuanling, intends to be listed on the main board of Shenzhen Stock Exchange

Development of trading system (VIII) -- Construction of low delay network

MySQL插入过程报错1062,但是我没有该字段。

La gamme NFT Color, qui représente la diversité, est en ligne sur la plate - forme du marché Sandbox

Color NFT series representing diversity launched on the sandbox market platform

Development of trading system (VII) -- Analysis of trading delay

Deveco studio 3.0 editor configuration tips

numpy np tips:使用opencv对数组插值放缩到固定形状 cv2.resize(res, dsize=(64, 64), interpolation=cv2.INTER_CUBIC)

文本关键词提取:ansj

How to quickly deliver high-value software
随机推荐
【LeetCode】22. 括号生成
【Proteus仿真】Arduino UNO按键控制数码管闪烁增/减显示
Configuration source code
Lao Ye's blessing
What is the difference between learning code, rolling code and fixed code? The number of repeated codes, coding capacity and the principle of rolling code
MySQL根据表前缀批量修改、删除表
【LeetCode】148. 排序链表
1.初识半音阶口琴
opencv怎么安装?opencv下载安装教程
MySQL modifies and deletes tables in batches according to the table prefix
Work assessment of Biopharmaceutics of Jilin University in March of the 22nd spring -00005
Simple integration of client go gin -update
Standing wave ratio calculation method
About PLSQL error initialization failure
Russian Airi Research Institute, etc. | SEMA: prediction of antigen B cell conformation characterization using deep transfer learning
web3.eth. Getpendingtransactions() returns null?
Intel 13代酷睿首次露出真面目:68MB缓存提升明显
The art of writing simple code
Oracle-sqlload import external data details
【Rust投稿】从零实现消息中间件(6)-CLIENT