第32天:安全开发-JavaEE应用&Servlet路由技术&JDBC&Mybatis数据库&生命周期

Snipaste_2025-06-15_00-50-56

新建一个项目运行Tomcat

Snipaste_2025-06-15_00-52-30

Snipaste_2025-06-15_00-57-20

这里1.8的版本是稳定的版本,我这里使用的tomcat是直接小迪课件中打包的,如果是正常来说去官网下载一个tomcat就行。可能报错 javaee9 至少需要 java11 支持,直接将 javaee9 换为 javaee8 即可..

Snipaste_2025-06-15_01-02-29

**Facet 的作用:**简单来说,Facet 的核心作用就是对软件的功能进行分类和组织,让开发者能够从不同的角度去看待和管理软件系统,从而提升开发和维护的效率。

Snipaste_2025-06-15_01-12-36

Snipaste_2025-06-15_01-12-54

Snipaste_2025-06-15_01-13-13

Snipaste_2025-06-15_01-14-09

Snipaste_2025-06-15_01-14-16

Snipaste_2025-06-15_01-18-09

Snipaste_2025-06-15_01-18-20

这里点击应用之后,创建成功后,我们下面添加javaEE相关的jar包,首先新建一个名为lib的目录。然后将需要的jar包复制到这个目录下,复制之后这个jar不能直接使用。

Snipaste_2025-06-15_01-22-51

需要点击文件菜单栏中的项目结构:

Snipaste_2025-06-15_01-23-47

这里选择库,然后点击+然后选择java。

Snipaste_2025-06-15_01-24-12

这里选择刚刚复制的jar包。

Snipaste_2025-06-15_01-24-43

点击确定,然后应用就行了。

Snipaste_2025-06-15_01-24-50

配置Tomcat

Snipaste_2025-06-15_01-30-05

这里选择本地的tomcat。

Snipaste_2025-06-15_01-30-18

然后发现这里有个修复,点击修复(其实就是没有加载项目):

Snipaste_2025-06-15_01-31-51

加载完项目之后,直接应用就行。然后运行的时候,报错了:说什么maven没有,然后从上图可以看到右下角有个找到Maven domo01构建脚本,点击加载项目就行了

Snipaste_2025-06-15_01-32-22

这里创建这个目录加上这个文件之后,应该需要声明路由,这里并没有声明,所以这里不能运行成功。我这里之后将整个项目重新删除创建,前面的步骤一样,我也没有在lib目录下复制任何的jar包,然后只是按照流程创建项目,然后运行tomcat,tomcat会自动生成一个默认的目录和界面。

Snipaste_2025-06-15_02-21-19

Snipaste_2025-06-15_02-21-09

Servlet生命周期

Snipaste_2025-06-15_11-19-29

参考文章:https://blog.csdn.net/qq_52173163/article/details/121110753

Servlet基础使用

首先在下图目录中创建一个java文件:IndexServlet

Snipaste_2025-06-15_11-37-18

Snipaste_2025-06-15_11-37-56

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.demo;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("------doget");
//super.doGet(req, resp);
}
}

Snipaste_2025-06-15_11-42-23

如何访问这个文件呢?

有两种方式。第一种就是修改web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">


<servlet>
<servlet-name>IndexServlet</servlet-name>
<servlet-class>com.example.demo.IndexServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>IndexServlet</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
</web-app>

Snipaste_2025-06-15_11-46-19

访问地址:http://localhost:8080/demo_war_exploded/index

Snipaste_2025-06-15_11-46-08

成功触发输出。

第二种就是直接在java文件中进行声明。

Snipaste_2025-06-15_11-52-57

接收一个GET请求,并且在页面中输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.example.demo;

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;
import java.io.PrintWriter;

@WebServlet("/a")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
//System.out.println(name);
PrintWriter out = resp.getWriter();
out.println("name=" + name);
System.out.println("------doget");
//super.doGet(req, resp);
}
}

这里的意思是首先接收一个name的值。

  1. PrintWriter out = resp.getWriter();
    这行代码的功能是获取一个输出流,这个输出流就像是一个 “数据管道”,服务器可以通过它把数据传输到浏览器。
  2. out.println(“name=” + name);
    这行代码的作用是把name=和变量name的值连接起来,形成一个完整的字符串,例如name=张三。然后,通过之前获取的 “数据管道”,将这个字符串发送到浏览器。

举个生活中的例子帮助你理解,这就好比你是一名客服人员,resp.getWriter()就相当于你拿到了一个可以和客户沟通的聊天窗口,而out.println()就相当于你在这个聊天窗口里输入并发送消息。

最终,在浏览器的页面上会显示出类似name=张三这样的内容。

Snipaste_2025-06-15_11-52-46

这里我使用的是/a的路径进行访问了,使用name进行参数的接收,然后输出name的值

接收一个post请求

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
package com.example.demo;

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;
import java.io.PrintWriter;

@WebServlet("/a")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
//System.out.println(name);
PrintWriter out = resp.getWriter();
out.println("name=" + name);
System.out.println("------doget");
//super.doGet(req, resp);
}


@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name= req.getParameter("name");
System.out.println(name);
PrintWriter out = resp.getWriter();
out.println("name=" + name);
System.out.println("------dopost");
//super.doPost(req, resp);
}
}

Snipaste_2025-06-15_12-22-52

1
2
3
4
5
System.out.println(name);		#这个是在终端中进行显示


PrintWriter out = resp.getWriter(); #这个是在web页面中进行显示
out.println("name=" + name); #输出

总代码

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
package com.example.demo;


import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/new")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
System.out.println("--------------NewServlet doGet");
}


@Override
public void init(ServletConfig config) throws ServletException{
System.out.println("--------------init");
// try {
// Class.forName("com.example.servletdemo.NewsServlet");
//
// } catch (ClassNotFoundException e) {
// throw new RuntimeException(e);
// }

}

@Override
public void destroy() {
System.out.println("--------------destroy");
super.destroy();
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("--------------http service");
super.service(req, resp);
}

@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("--------------Servlet service");
super.service(req, res);
}
}

Snipaste_2025-06-15_12-26-45

1
2
3
4
5
6
7
8
9
10
11
12
13
在访问http://localhost:8080/demo2_war/index?id=1时

init只会被执行一次之后不会再执行

destroy会在最后结束服务器的时候执行

service会执行多次

注意:

service执行在doget,dopost之上

先执行Servlet service后执行http service再执行doGet

Snipaste_2025-06-15_12-39-06

当我停止服务的时候就会执行销毁:

Snipaste_2025-06-15_12-43-23

丰富post提交代码

1
2
3
4
5
6
7
8
9
10
11
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String name = req.getParameter("name");
resp.setContentType("utf-8");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("这是post提交的数据");
out.println(name);
out.flush();
out.close();
System.out.println("--------------doPost");

代码详解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String name = req.getParameter("name");//理解为定义字符串name,给予给定值name。

resp.setContentType("utf-8");//编码方式设置为utf-8

resp.setContentType("text/html");//回显方式为text/html

PrintWriter out = resp.getWriter();//数据输出

out.printIn("这是post提交的数据");//页面上显示这是post提交的数据。

out.printin(name);//页面上输出(当给予name值时)

out.flush();//页面刷新

out.close();//关闭

System.out.printIn("-------------doPsot")//系统输出----------dopost

Snipaste_2025-06-15_12-50-39

JavaEE-数据库-JDBC&Mybatis&库

1
2
3
4
5
6
7
8
9
10
11
12
13
数据库下载:
三种数据库的对比,使用,分析:
https://blog.csdn.net/K_520_W/article/details/127023655

JDBC的使用:
https://www.jianshu.com/p/ed1a59750127

JDBC由于是java官方自带,所以不需要api接口,但需要数据库驱动jar文件

jar文件下载:
https://mvnrepository.com/

下载后maven会出现文件:(许多使用拉数据库的操作都会使用)

首先在你的项目的根目录创建一个lib目录,然后在将下载的jar包,放到里面 ,回到IDEA,将这个jar右键,添加为库,就可以了

Snipaste_2025-06-15_12-46-58

Snipaste_2025-06-15_13-12-28

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
package com.example.demo;

import java.sql.*;


public class MyselectServlet{
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 加载 MySQL 驱动程序
Class.forName("com.mysql.jdbc.Driver");
String url ="jdbc:mysql://localhost:3306/demo01";
// 通过调用 DriverManager.getConnection() 方法,你可以获取到一个 Connection 对象,
// 该对象表示与数据库的连接。你可以使用这个 Connection 对象执行 SQL 语句和事务操作。
Connection connection = DriverManager.getConnection(url,"root","root");
System.out.println(connection);
String sql="select * from demo01";
//危险写法
//String vulsql="select * from news where id="+id;
//预编译写法
String safesql="select * from demo01 where id=?";
System.out.println(sql);
// connection.createStatement() 是用来创建一个 Statement 对象,
Statement statement= connection.createStatement();
// 而 statement.executeQuery(sql) 是用来执行 SQL 查询并返回结果集。
ResultSet resultSet = statement.executeQuery(sql);
// resultSet.next() 方法用于将结果集的指针移动到下一行,并返回一个布尔值,
// 表示是否还有更多行可供遍历。通过使用 while 循环,可以在结果集还有下一行的情况下不断迭代。
while (resultSet.next()){
// resultSet.getInt("id") 用于获取当前行 "id" 列的整数值,并将其赋给变量 id。
int id = resultSet.getInt("id");
String page_title = resultSet.getString("page_title");
String heading = resultSet.getString("heading");
String subheading = resultSet.getString("subheading");
String content = resultSet.getString("content");
String img = resultSet.getString("img");
System.out.println(id+"|"+page_title+"|"+heading+"|"+subheading+"|"+content+"|"+img);
}
}
}

危险写法:

1
String vulsql="select * from news where id="+id;	#就是这个值的后面是一个变量

预编译写法:

1
2
String safesql="select * from demo01 where id=?";			
#预编译简单来说就是程序提前将语句的格式进行固定,当你拼接其他语句的时候会按照两条语句进行看待,只要你输出的值中包含了MySQL的函数的一些关键字,那么就不会带入到数据库进行查询。