0%

实现动态网页开发(下)

本文操作仅供参考,西北民族大学21级计科2班WEB开发基础91704X08教师孟老师实验笔记

一、Servlet

1) Servlet是什么

Servlet是Java提供的一门动态web资源开发技术

Servlet 是javaEE规范之一,其实就是一个接口,将来我们需要定义 Servlet 类实现 Servlet接口 ,并由 web 服务器运行Servlet

image-20231222090452212

2)servlet快速入门

概念︰运行在服务器端的小程序
Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。

将来我们自定义一个类,实现servlet接口,复写方法。

快速入门:

1.创建JavaEE项目

2.定义一个类,实现servlet接口

1
public class servletDemo1 implements servlet

3.实现接口中的抽象方法
4.配置servlet
在web.xml中配置︰

1
2
3
4
5
6
7
8
9
10
11
<!--配置servlet -->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>
cn.itcast.web.servlet.servletDemo1
</servlet-class>
</ servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</ servlet-mapping>

2)Maven Web项目使用Servlet

在pom中导入坐标

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>

建立类,实现servlet接口,并重写接口方法

image-20231222092250496

加上@WebServlet("/demo1")注解配置该Servlet的访问路径

启动项目后访问http://localhost:8080/jspTest_war/demo1

image-20231222092428074

获取成功

3) Servlet生命周期

Servlet运行在servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:

1.加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建servlet对象

2.初始化:在servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

3.请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。

4.服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个servlet实例,该实例随后会被Java的垃圾收集器所回收

二、创建前端页面

1)登陆页面

简单的使用post方法进行提交表单的jsp页面,命名为index.jsp作为第一页面展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>登录界面</title>
</head>
<body>
<form action="LoginServlet" method="post">
用户名:<input type="text" id="userId" name="userName" placeholder="输入用户名" /><br>
密码:<input type="password" id="pwdId" name="pwdName" placeholder="输入密码" /><br>
<button type="submit">登录</button><br>
<a href="register.jsp">没有账号?先去注册</a>
</form>
</body>
</html>

2)注册界面

下面是注册界面的代码,和登录界面类似,注册时一般都会让你的密码输入两次,进行比对。命名为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>注册界面</title>
</head>
<body>
<form action="RegisterServlet" method="post">
用户名:<input type="text" id="userId" name="userName" placeholder="输入用户名" /><br>
密码:<input type="password" id="pwdId1" name="pwdName1" placeholder="输入密码" /><br>
密码:<input type="password" id="pwdId2" name="pwdName2" placeholder="再次输入密码" /><br>
<button type="submit">注册</button>
</form>
</body>
</html>

三、后端数据处理

1.创建数据库

使用

1
CREATE TABLE user( username VARCHAR(50), password VARCHAR(50) );

image-20231225205206144

image-20231225205222092

2.配置mybatis

在pom中引入坐标

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.15</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.1.0</version>
</dependency>

3.建立controller

在src下创建一个包命名为controller,这是用来接收和发送请求处理的控制层,主要用来连接前段和后端的。

在controller中建立LoginServlet类用来处理login数据

并使用extends继承HttpServlet,并写入doPost方法,如下图所示

image-20231225202941373

完善LoginServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package controller;

import java.io.IOException;
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 javax.servlet.http.HttpSession;

import entity.User;
import service.UserService;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

// 创建UserService对象
private UserService userService = new UserService();

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 1. 获取参数 2. 验证用户 3. 返回结果
*/
/**
* 1.获取参数
* request.getParameter("userName");这里面的参数username就是前端<input>标签中的name,切勿写错
*/
String username = request.getParameter("userName");
String password = request.getParameter("pwdName");

// 调用userService对象中的login方法验证登录用户
User user = userService.login(username,password);
System.out.println(user==null);

if (user != null) {
// 用户不为空,代表用户存在,成功登录
System.out.println("登录成功");

/*
* 创建一个session用来存储user
* session是javaweb中一个负责存储数据的,相当于你的钥匙包,此时的user便是其中的一个钥匙,
* 将user存入包内,需要的时候在取出来,在前端jsp页面非常好用,不明白的同学可以去学一下这里就不赘述了
* */
HttpSession session = request.getSession();
session.setAttribute("user", user);

// 登录成功后,通过转发跳转到新的界面,当然也可以使用重定向,我们这里为了简单采用转发,若是想转发其他界面只要修改loginSuccess.jsp即可
request.getRequestDispatcher("loginSuccess.jsp").forward(request, response);// 转发
} else {
// user为空,代表用户不存在
System.out.println("登陆失败");
// 登录失败通过转发,在回到登录界面继续进行登录
request.getRequestDispatcher("index.jsp").forward(request, response);// 转发
}

}

}

完善RegisterServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.inmb.web.controller;

import com.inmb.web.entity.User;
import com.inmb.web.service.UserService;

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;

/**
* @项目: jspTest
* @描述: 注册
* @作者: i囡漫笔
* @创建时间: 2023-12-25 21:18
**/

@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

// 创建UserService对象
private UserService userService = new UserService();

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 1.获取参数
* 2.调用service处理
* 3.返回结果
*/

// 获取前端输入的两次密码
String pwd1 = request.getParameter("pwdName1");
String pwd2 = request.getParameter("pwdName2");

// 创建user对象,将前端输入的内容存入里面
User user = new User();
user.setUsername(request.getParameter("userName"));

if(pwd1.equals(pwd2)){
// 判断密码输入是否相同(其实这里我们可以用JavaScript在前端进行判断输入内容是否相同,如果相同在获取,这样在servlet中就不用判断了)
user.setPassword(pwd1);

// 根据user里的内容进行注册
int row = userService.register(user);
System.out.println("改变的行数:"+row);

// 返回结果,产生几个注册信息row等于几,例如一个人注册row=1
if (row > 0) {
System.out.println("注册成功");
//跳转注册成功界面,注册成功后,通过转发跳转到新的界面,当然也可以使用重定向,我们这里为了简单采用转发,若是想转发其他界面只要修改registerSuccess.jsp即可
request.getRequestDispatcher("registerSuccess.jsp").forward(request, response);
} else {
//跳转注册界面并提示错误信息
System.out.println("注册失败");
request.getRequestDispatcher("register.jsp").forward(request, response);
}

}else {
// 两次输入密码不同
System.out.println("两次密码不同,登录失败");
request.getRequestDispatcher("register.jsp").forward(request, response);
}
}
}

4.建立包

先在src中创建几个包,分别是service,dao,entity,utils。

  1. service层(业务层):封装通用的业务逻辑,操作;与数据层的交互。
  2. dao层(数据层):主要做数据持久层的工作,封装负责与数据库进行操作的代码。
  3. entity :实体类。
  4. utils :封装工具类。

5.实体类建立

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.inmb.web.entity;
/**
* @项目: jspTest
* @描述: 用户实体类
* @作者: i囡漫笔
* @创建时间: 2023-12-25 20:53
**/
public class User {
// 这里比对数据库表中的字段,表中创建了id,username,password三个字段
// id
private int id;
// username
private String username;
// password
private String password;

// 生成get和set方法
public int getId() {
return id;
}
public void setId(int 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;
}

// 重写toString方法
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
}

}

6.工具类实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.inmb.web.utils;

import java.sql.*;

/**
* @项目: jspTest
* @描述: 连接数据库
* @作者: i囡漫笔
* @创建时间: 2023-12-25 21:14
**/

public class DBUtils {

// 加载驱动
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

public static Connection getConnection() throws SQLException {

String url = "jdbc:mysql://localhost:3306/111?characterEncoding=UTF-8&&useSSL=false";
Connection connection = DriverManager.getConnection(url, "root", "root");
return connection;
}

// 关闭资源
public static void close(ResultSet resultSet, Statement statement, Connection connection) throws SQLException {

if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}
}

7.数据层建立

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.inmb.web.dao;

import com.inmb.web.entity.User;
import com.inmb.web.utils.DBUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @项目: jspTest
* @描述: dao包
* @作者: i囡漫笔
* @创建时间: 2023-12-25 21:10
**/

public class UserDao {
/**
* @描述: 用户登陆
* @Param: [username]
* @返回: com.inmb.web.entity.User
* @作者: i囡漫笔
* @日期: 2023/12/25
*/
public User login(String username) throws Exception {

// 获取数据库操作链接
Connection connection = DBUtils.getConnection();

// 创建statement并执行sql
String sql = "SELECT * FROM user WHERE username = ? ";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, username);
// 获取数据集
ResultSet resultSet = statement.executeQuery();

// 创建一个空的user用于接收查询到的数据
User user = null;

// 处理结果集
while (resultSet.next()) {
user = new User();
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
System.out.println(user);
}

// 5.关闭资源
DBUtils.close(resultSet, statement, connection);

return user;
}
/**
* @描述: 用户注册
* @Param: [user]
* @返回: int
* @作者: i囡漫笔
* @日期: 2023/12/25
*/
public int register(User user) throws SQLException{
// 获取链接
Connection connection = DBUtils.getConnection();

String sql = "INSERT INTO user (username,password) VALUES (?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, user.getUsername());
statement.setString(2, user.getPassword());
// 执行sql语句,如果成功添加数据,row>0
int row = statement.executeUpdate();

// 关闭资源
DBUtils.close(null, statement, connection);

// 返回数据
return row;
}

}

8.service实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.inmb.web.service;

import com.inmb.web.dao.UserDao;
import com.inmb.web.entity.User;

import java.sql.SQLException;

/**
* @项目: jspTest
* @描述: 业务层处理
* @作者: i囡漫笔
* @创建时间: 2023-12-25 21:16
**/

public class UserService {
// 创建UserDao对象
private UserDao userDao = new UserDao();

/**
* 登录操作
* @param username
* @param password
* @return
*/
public User login(String username, String password) {
// 声明一个用户实体类,用于接收返回的user
User user = null;
try {
// 调用userDao中方法根据用户名查询是否存在该用户
user = userDao.login(username);

if (!user.getPassword().equals(password)) {
// 密码不相等时将user置为null
System.out.println("密码不对");
user = null;
}
} catch (Exception e) {
e.printStackTrace();
}

// 返回user数据
return user;
}

/**
* 用户注册
* @param user
* @return row
*/
public int register(User user) {
// 首先定义row=0,若有新用户注册,row>0,如果没有注册返回0
int row = 0;
try {
row = userDao.register(user);
} catch (SQLException e) {
e.printStackTrace();
}
return row;
}

}

四、成果验证

image-20231225213710228

image-20231225213733315

最终框架架构如下

image-20231225213848729

五、

由于时间紧迫没有仔细的编写JSP文件以及登陆成功后的后续。

个人认为servlet比springboot更加麻烦,Servlet项目流程复杂,容易出错。有人说“某种程度上,Servlet 就是 Spring Boot 的底层基础代码”,确实是这样Spring Boot上有很多MVC的影子。在学习完springboot后在使用Servlet有点熟悉的感觉

技术分享,如果您觉得内容不错的话不妨进行打赏,您的支持将鼓励我继续创作!


如果你对本文有看法或更好的见解可以点击下方按钮进行评论
*注:本站为非交互网站
此按钮将会转跳至评论站点 i-nmb.chat 进行评论
  • 本文作者: i囡漫笔
  • 本文链接: https://i-nmb.cn/servlet.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

欢迎关注我的其它发布渠道