# 一、JavaWeb

# 1. 基本概念

# 1.1、分类

  • 静态 web:
  • 动态 web:Servlet/JSP,ASP,PHP

# 1.2、web 应用程序

web 应用程序:可以提供浏览器访问的程序

# 1.3、技术

JSP/Servlet:

​ B/S: 浏览器服务器

​ C/S: 客户端服务器

# 2.web 服务器

IIS

微软的: ASP…,windows 中自带的

Tomcat

​ Tomcat 是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun 和其他一些公司及个人共同开发而成。由于有了 Sun 的参与和支持,最新的 Servlet 和 JSP 规范总是能在 Tomcat 中得到体现,Tomcat 5 支持最新的 Servlet 2.4 和 JSP 2.0 规范。因为 Tomcat 技术先进、性能稳定,而且免费,因而深受 Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的 Web 应用服务器。

# 3.TomCat

配置环境变量: jdk,tomcat --> startup.bat 启动服务

tomcat 默认端口: 8080

mysql: 3306
http: 80
https: 443

# 4.Http

略,内容比较多,且很重要

# 5.Maven

为什么需要 maven

1. 在 javaweb 开发中,需要大量 jar 包,如果不用 maven 需要很复杂的手动导入;
2. 利用 maven 自动导入和配置 jar 包

# 5.1Maven 项目架构管理工具

Maven 的核心思想: 约定大于配置

  • 有约束,不要去违反

# 5.2 下载安装

[Maven 下载地址](Index of /dist/maven/maven-3 (apache.org))

# 5.3 环境变量

image-20221130143107012

# 5.4 配置国内镜像

1
2
3
4
5
6
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

# 5.5 本地仓库

建立本地仓库: localRepository

1
<localRepository>F:\Environment\Maven\apache-maven-3.8.6-bin\apache-maven-3.8.6\maven-repo</localRepository>

# 5.6 在 IDEA 中使用 Maven (配置 tomcat)

image-20221130154431906
  1. 启动 IDEA
  2. 创建一个 MavenWeb 项目
  3. 配置
image-20221130155203588

​ 4. 等待仓库初始完毕
image-20221130155949899

​ 5. 配置 Tomcat

image-20221201004821915 image-20221130163014509 image-20221201004916411

​ 6.Maven 依赖包.

1
2
3
4
5
6
7
8
9
    <dependencies>
<!-- 具体依赖的jar包配置文件-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>

</dependencies>

​ 7. 解决配置文件 无法导出失效的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

# 5.7 在 IDEA 中创建非 Maven 的 javaweb 项目

新建项目 ->javaEE->web Application

# 6.servlet

什么是 servlet?

​ 由 java 编写的程序,运行在 web 服务器上,用来处理来自客户端的请求,返回 html 页面,在客户端形成动态网页。可跨平台.

本质上来讲: servlet 就是一种实现了 servlet 接口的类,由 web 容器负责创建并调用,用于接收和响应用户的请求。

# 6.1 在项目中配置 servlet

image-20221201005040727

# 6.2 两种配置 web.xml 的方式

  1. 用 <servlet> 标签

    image-20221201005235062
  2. 用 @WebServlet 注解

    image-20221201005307929

# 6.3 项目结构

image-20221201091903042

1
2
3
4
5
6
7
8
9
10
11
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
PrintWriter writer = response.getWriter();
writer.write("this is Post");
Student stu = new Student();
stu.setStuid("001");
stu.setStuname("张三");
//用fastjson将数据转化为json对象
writer.write(JSON.toJSONString(stu));
}

# 6.4 中文乱码

image-20221201092114864

# 方法一

  1. 设置 HTTPServletResponse 使用 utf-8 编码

    response.setCharacterEncoding("utf-8");

  2. 通知浏览器使用 utf-8 解码

    response.setHeader("Content-Type","text/html;charset=utf-8");

# 方法二

​ 包含方法一中的两个功能
response.setContentType("text/html;charset=utf-8");
注意要放在开头

image-20221201094338943

# 6.5 数据转 json

  1. fastjson.jar

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //用fastjson将java对象转化为json对象
    writer.write(JSON.toJSONString(stu));
    //将集合转化为json
    List<Student> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
    Student s = new Student("20203106150"+i,"鲁班"+i+"号");
    list.add(s);
    }
    writer.write(JSON.toJSONString(list));
  2. gson.jar

         //用Gson转换
         Gson gson = new Gson();
         writer.write(gson.toJson(stu));
         writer.write(gson.toJson(list));
    
  3. jackson.jar

    1
    2
    3
    4
    //jackson      
    ObjectMapper mapper = new ObjectMapper();
    writer.write(mapper.writeValueAsString(stu));
    writer.write(mapper.writeValueAsString(list));

# 7.JDBC

image-20221201110106611

  1. 导入 jar 包
  2. 注册驱动
  3. 创建连接
  4. 定义 SQL 语句
  5. 获取执行 SQL 对象
  6. 执行 SQL 并处理结果
  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

//JDBC
//第一步: 导入jar包 mysql-connector-java.jar 注意对应mysql版本


List<Users> userList = new ArrayList<>();

try {
//第二步: 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//第三步: 创建连接
String url = "jdbc:mysql://127.0.0.1:3306/javaeestudy";
String username = "root";
String password = "248789";
Connection con = DriverManager.getConnection(url, username, password);
//第四步: 定义SQL语句
Statement stmt = con.createStatement();
String sql = "select * from users";
//第五步: 获取执行SQL对象
ResultSet rs = stmt.executeQuery(sql);
//第六步: 执行SQl 处理结果
while (rs.next()) {
Users user = new Users();
user.setUserid(rs.getInt("userid"));
user.setUsername(rs.getString("username"));
user.setUserpsd(rs.getString("userpsd"));
userList.add(user);
}
//第七步: 释放资源
rs.close();
stmt.close();
con.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
writer.write(JSON.toJSONString(userList));

# 8. 项目结构 + 基本功能

项目结构

src 中放后端代码

  1. **controller ** 负责请求转发,接受页面过来的参数,传给 Service 处理,接到返回值,再传给页面。
  2. dao 一定是和数据库的某一张表一一对应的,其中封装了增删改查基本操作,建议 DAO 只做原子操作,增删改查。
  3. entity 存放需要操作的实体类,如 (user,person,student)。
  4. service 一个或多个 DAO 进行的再次封装,封装成一个服务,所以这里也就不会是一个原子操作了,需要事物控制。
  5. utils 工具包,将一些重复的操作解耦封装进来,如数据库连接,资源释放等。

# 8.1. 添加数据

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
//-------------   Dao  -------------
public int addUser(Users user) {
int ret = 0;
// 1. 导入jar包
// 2. 注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 3. 创建连接
String url = "jdbc:mysql://127.0.0.1:3306/javaeestudy";
String username = "root";
String password = "248789";
Connection con = DriverManager.getConnection(url, username, password);
// 4. 定义SQL语句
String sql = "INSERT INTO users(username, userpsd)values(?,?)";
// 5. 执行SQL并处理结果
PreparedStatement pst = con.prepareStatement(sql);
pst.setString(1, user.getUsername());
pst.setString(2, user.getUserpsd());
ret = pst.executeUpdate();
// 6. 释放资源
stmt.close();
con.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return ret;
}

//-------------- addUserServlet ------------------
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");

PrintWriter writer = response.getWriter();
Users users = new Users(request.getParameter("username"),request.getParameter("userpsd"));

//调用服务层add
usersService usersService = new usersServiceImpl();
int ret = usersService.addUser(users);
if (ret > 0) {
writer.write("数据添加成功!");
} else {
writer.write("失败");
}

}

# 9. 思考优化

# 9.1 封装数据库连接类,放入 utils 工具包

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
package com.jilin.utils;

import java.sql.*;

public class MySqlUtil {
//封装连接数据库
public static Connection getConn(){
Connection con = null;
try{
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/javaeestudy";
String username = "root";
String password = "248789";
con = DriverManager.getConnection(url, username, password);
}catch(Exception e){
e.printStackTrace();
}
return con;
}
//封装释放资源
public static void close(ResultSet rs, Statement stmt, Connection con){
try{
if(rs!=null){rs.close();}
if(stmt!=null){stmt.close();}
if( con!=null){con.close();}
}catch(Exception e){
e.printStackTrace();
}
}
//重载用于 Pst
public static void close(PreparedStatement pst, Connection con){
try{
if(pst!=null){pst.close();}
if( con!=null){con.close();}
}catch(Exception e){
e.printStackTrace();
}
}
}

# 9.2 优化 servlet 事务,抽象封装

​ 只需要一个 Servlet 类 —— indexServlet

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 com.jilin;
import ...

@WebServlet(name="indexServlet", urlPatterns = "/")
public class indexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
start(req,resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
start(req, resp);
}

private void start(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();

//第一种方法
//这是把servlet汇总到一个类 现在调用
/* userController usercontroller = new userController();

String type = req.getParameter("type");
if(type.equals("add")){
int ret = usercontroller.addUser(req);
writer.write(ret);
}
if(type.equals("list")){
List<Users> list = usercontroller.getList(req);
writer.write(JSON.toJSONString(list));
}*/

//第二种方法 实用 反射获取[path]路径

//获取路径字符串
String path = req.getServletPath();
//获取类名称
String className = path.substring(1, path.lastIndexOf("/"));
//获取方法名称
String methodName = path.substring(path.lastIndexOf("/") + 1);
System.out.println(className + "," + methodName);
//通过反射调用类的方法
try {
Class<?> clazz = Class.forName("com.jilin.controller." + className);
//创建类的对象 相当于new了一个
Object instance = clazz.getConstructor().newInstance();
Method method = clazz.getMethod(methodName,HttpServletRequest.class);
//调用方法
Object object = method.invoke(instance, req);
writer.write(JSON.toJSONString(object));
} catch (Exception ex) {
ex.printStackTrace();
}

}
}

利用 反射 调用 userController 类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.jilin.controller;
import ...

public class userController {
public int addUser(HttpServletRequest request){
Users users = new Users(request.getParameter("username"),request.getParameter("userpsd"));
usersService usersService = new usersServiceImpl();
int ret = usersService.addUser(users);
return ret;
}
public List<Users> getList(HttpServletRequest request){
//调用服务层
usersService usersservice = new usersServiceImpl();
List<Users> list = usersservice.getList();
return list;
}
}

# 10. 过滤器 Filter

过滤器图示

# 10.1 过滤器解决乱码

新建一个 filter 过滤器,主要方法有三个 init() , doFilter() , destroy()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

@WebFilter(urlPatterns = "*") //注解 url设置应用到所有路径页面
public class CharaterEncoding implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

filterChain.doFilter(request,response);
}
@Override
public void destroy() {

}
}

# 10.2 过滤器解决跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@WebFilter("/*")
public class CORSFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 响应标头指定 指定可以访问资源的URI路径
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
//响应标头指定响应访问所述资源到时允许的一种或多种方法
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
//设置 缓存可以生存的最大秒数
response.setHeader("Access-Control-Max-Age", "3600");
//设置 受支持请求标头
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
// 指示的请求的响应是否可以暴露于该页面。当true值返回时它可以被暴露
response.setHeader("Access-Control-Allow-Credentials","true");
filterChain.doFilter(servletRequest, servletResponse);
}
}

暂时先写这么多吧,基本上都是跟着老师视频做的,感觉还需要多熟悉多理解。 2022/12/3