JavaWeb
什么是JavaWeb?
JavaWeb是指基于Java技术的Web应用程序开发。它包括使用Java语言编写的服务器端代码,用于处理客户端请求和生成动态网页内容。JavaWeb应用程序通常运行在Web服务器上,如Apache Tomcat、Jetty等,并通过HTTP协议与客户端进行通信。
JavaWeb开发涉及多种技术和框架,如Servlet、JSP(JavaServer Pages)、Spring MVC、Hibernate等。这些技术和框架可以帮助开发人员构建可扩展、可维护的Web应用程序。
JavaWeb应用程序通常包括以下几个部分:
- 客户端:用户通过浏览器或其他客户端应用程序访问Web应用程序。
- 服务器端:Web服务器(如Apache Tomcat)运行Java代码,处理客户端请求并生成动态网页内容。
- 数据库:Web应用程序通常需要与数据库进行交互,以存储和检索数据。常用的数据库有MySQL、Oracle、PostgreSQL等。
- 应用程序逻辑:Java代码处理业务逻辑,如用户认证、数据验证、数据处理等。
JavaWeb开发需要掌握HTML、CSS、JavaScript等前端技术,以及Java编程语言和相关的Web开发框架。通过学习和实践,可以开发出功能丰富、性能良好的Web应用程序。
Web服务器
Web服务器是一种运行在服务器上的软件,用于处理客户端(如浏览器)的HTTP请求,并提供相应的网页内容。Web服务器的主要功能包括:
- 接收客户端请求:Web服务器监听客户端的HTTP请求,并解析请求的URL、方法、头部等信息。
- 解析请求:Web服务器根据请求的URL,找到对应的资源(如HTML文件、图片、视频等),并将其发送给客户端。
- 生成动态内容:Web服务器可以执行Java代码或其他脚本语言,生成动态网页内容,并将其发送给客户端。例如,使用Servlet、JSP等技术,可以根据客户端请求生成动态的HTML页面。
Tomcat
Tomcat是一个开源的Java Servlet容器,用于运行Java Web应用程序。它支持Servlet和JSP规范,并提供了丰富的配置选项和扩展功能。
下载和安装
- 下载Tomcat:从Apache Tomcat官方网站(https://tomcat.apache.org/)下载最新版本的Tomcat。
- 解压Tomcat:将下载的Tomcat压缩包解压到本地目录。
- 配置环境变量:将Tomcat的bin目录添加到系统的PATH环境变量中,以便在命令行中直接运行Tomcat命令。
启动Tomcat
- 打开命令行窗口。
- 进入Tomcat的bin目录。
- 运行startup.sh(Linux/Mac)或startup.bat(Windows)脚本,启动Tomcat服务器。
配置Tomcat
Tomcat的配置文件位于conf目录下,主要包括server.xml和web.xml两个文件。
- server.xml:用于配置Tomcat服务器的全局参数,如端口号、连接数、虚拟主机等。
- web.xml:用于配置Web应用程序的参数,如Servlet、Filter、Listener等。
部署Web应用程序
将Web应用程序的文件(如HTML、JSP、Java类等)放置在Tomcat的webapps目录下,即可通过浏览器访问该应用程序。例如,将Web应用程序放置在webapps/myapp目录下,可以通过http://localhost:8080/myapp访问该应用程序。
停止Tomcat
- 打开命令行窗口。
- 进入Tomcat的bin目录。
- 运行shutdown.sh(Linux/Mac)或shutdown.bat(Windows)脚本,停止Tomcat服务器。
HTTP协议
HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于在Web浏览器和服务器之间传输超文本的协议。它定义了客户端和服务器之间的通信规则,包括请求和响应的格式、方法、状态码等。
HTTP请求
HTTP请求由请求行、请求头和请求体组成。
请求行:包含请求方法、请求URL和HTTP版本。例如,GET /index.html HTTP/1.1。
请求方法
HTTP请求方法用于指定对资源的操作类型。常见的请求方法包括:
- GET:获取资源,可以添加少量参数,会在url中直接显示,有参数数量限制,不安全,但高效。
- POST:提交数据,可以添加没有限制的参数,参数在请求体中,安全,但效率低。
- PUT:更新资源。
- DELETE:删除资源。
- HEAD:获取资源的元数据。
- OPTIONS:获取资源支持的请求方法。
- PATCH:部分更新资源。
请求URL
请求URL指定了要访问的资源的位置。例如,http://www.example.com/index.html。
HTTP版本
HTTP版本指定了客户端和服务器之间通信的协议版本。常见的HTTP版本包括HTTP/1.0和HTTP/1.1,它们的区别是HTTP/1.1支持持久连接,可以复用TCP连接,提高效率。
请求头:包含客户端请求的元数据,如请求类型、客户端信息、请求参数
常见的请求头
- Host:指定请求的主机名和端口号。
- User-Agent:指定客户端浏览器的类型和版本。
- Accept:指定客户端可以接收的内容类型。
- Accept-Language:指定客户端可以接收的语言。
- Accept-Encoding:指定客户端可以接收的内容编码。
- Cookie:指定客户端发送给服务器的Cookie信息。
请求体:包含客户端发送给服务器的数据,如表单数据、JSON数据等。
HTTP响应
HTTP响应由状态行、响应头和响应体组成。
状态行:包含HTTP版本、状态码和状态消息。例如,HTTP/1.1 200 OK。
状态码
HTTP状态码用于表示服务器对请求的处理结果。常见的状态码包括:
- 1xx:信息性状态码,表示请求已被接收,继续处理。
- 2xx:成功状态码,表示请求已被成功处理。
- 3xx:重定向状态码,表示请求的资源已被移动,需要进一步操作。
- 4xx:客户端错误状态码,表示请求有误,服务器无法处理。
- 5xx:服务器错误状态码,表示服务器处理请求时发生错误。
状态消息
状态消息是对状态码的简要描述,例如,OK表示请求已被成功处理。
响应头:包含服务器响应的元数据,如内容类型、内容长度、服务器信息等。
常见的响应头
- Content-Type:指定响应的内容类型。
- Content-Length:指定响应的内容长度。
- Server:指定服务器的类型和版本。
- Date:指定响应的时间。
- Last-Modified:指定资源的最后修改时间。
- Set-Cookie:指定服务器发送给客户端的Cookie信息。
响应体:包含服务器返回给客户端的数据,如表单数据、JSON数据等。
Maven的作用
Maven是一个项目管理和构建工具,它可以帮助开发者管理项目的依赖、构建项目、生成文档等。Maven的主要作用包括:
- 管理项目依赖:Maven可以自动下载和管理项目的依赖,包括第三方库和插件。开发者只需要在pom.xml文件中声明依赖,Maven会自动下载并添加到项目中。
- 构建项目:Maven可以自动编译、测试和打包项目。开发者只需要运行一个命令,Maven会自动完成这些任务,并生成可部署的文件。
- 生成文档:Maven可以自动生成项目的文档,包括API文档、项目报告等。开发者只需要运行一个命令,Maven会自动生成这些文档。
- 项目版本管理:Maven可以管理项目的版本,包括SNAPSHOT版本和Release版本。开发者可以轻松地发布和管理项目的版本。
Maven的下载安装
Maven的下载和安装非常简单,只需要从官方网站(https://maven.apache.org/download.cgi) 下载最新版本的Maven,并按照安装向导进行安装即可。
配置系统环境变量
需要配置如下的环境变量:
- MAVEN_HOME:Maven的安装目录。
- M2_HOME:Maven的安装目录下的bin目录。
- PATH:将Maven的bin目录添加到PATH环境变量中。
Maven的配置
Maven的配置文件是settings.xml,它位于Maven的安装目录下的conf文件夹中。settings.xml文件中包含了Maven的配置信息,如本地仓库的位置、远程仓库的地址等。
本地仓库
本地仓库是Maven用来存储项目依赖的本地目录。默认情况下,Maven会将本地仓库存储在用户主目录下的.m2/repository文件夹中。开发者可以通过修改settings.xml文件中的localRepository元素来指定本地仓库的位置。
mirror
mirror元素用于配置Maven的镜像仓库。镜像仓库是远程仓库的副本,它可以在远程仓库无法访问时提供替代的下载服务。开发者可以通过在settings.xml文件中添加mirror元素来配置镜像仓库。
在IDEA中配置Maven
-
创建一个Maven项目
-
点开项目结构
-
新建一个网页index.jsp
-
再次点开项目结构,创建一个工件
-
配置tomcat
添加工件
- 简单修改之前index.jsp,测试运行
Servlet
什么是Servlet
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
开发Servlet程序的步骤
- 编写一个Java类,实现Servlet接口。
- 在web.xml文件中配置Servlet的映射关系。
- 编译并部署Servlet程序到Web服务器中。
- 启动Web服务器,访问Servlet程序。
在Idea中开发一个Servlet程序
-
依据上面的步骤创建好Maven的Web项目
-
在Java目录下创建继承自HttpServlet的类
package com.myLearning;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Servlet helloServlet</title>");
writer.println("</head>");
writer.println("<body>");
writer.println("<h1>Servlet helloServlet23333333333</h1>");
writer.println("</body>");
writer.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 在pom.xml中添加Servlet所需要依赖
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version> <!-- 使用适合的版本 -->
</dependency>
</dependencies>
- 在web.xml中配置Servlet
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.myLearning.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 配置并启动Tomcat服务器,测试
Servlet原理
web服务器在收到浏览器请求之后,会生成请求和响应这两个对象,然后会去web.xml中查找对应的servlet,然后调用servlet中的service方法,service方法会根据请求方式调用doGet或者doPost方法,然后设置相应对象,最终由web服务器将响应返回给浏览器。
mapping配置
- 一个servlet可以配置多个mapping
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
- 通配符配置
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
- 优先级问题
ServletContext
ServletContext是什么?
每一个web工程都有一个ServletContext对象,代表当前web工程,是web工程的一个全局对象,由web容器创建,可以用来在多个servlet程序之间共享数据,获取web工程配置信息,获取资源文件等。
共享资源
- 设置servletContext的属性
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class setString extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取上下文
ServletContext servletContext = this.getServletContext();
String name = "vertin";
servletContext.setAttribute("name", name);
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>get</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1 > have set name </h1>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 获取servletContext的属性
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class getString extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取上下文
ServletContext servletContext = this.getServletContext();
String name = (String)servletContext.getAttribute("name");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>get</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1 >" + name + " </h1>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取初始化参数
// 获取参数
String name = (String)servletContext.getInitParameter("hello");
请求转发
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class dispatch extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取上下文
ServletContext servletContext = this.getServletContext();
// 将请求转发给刚刚的获取参数的程序
servletContext.getRequestDispatcher("/getParam").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
读取资源文件
创建配置资源文件
查看资源最后放置的路径
读取资源文件中的内容
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
public class getProperties extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取上下文
ServletContext servletContext = this.getServletContext();
// 获取db.properties配置文件中的内容
InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(inputStream);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().println(username + ":" + password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
HttpServletResponse类
HttpServletResponse 是 Java Servlet API 中的一个核心接口,用于表示服务器对客户端的 HTTP 响应。它提供了设置响应状态、响应头、响应体等方法,使开发者能够控制服务器返回给客户端的内容和行为。
常用方法
setStatus(int sc)
:设置响应的状态码。setHeader(String name, String value)
:设置响应头。setContentType(String type)
:设置响应的内容类型。getOutputStream()
:获取输出流,用于向客户端发送二进制数据。getWriter()
:获取字符输出流,用于向客户端发送文本数据。sendRedirect(String location)
:发送重定向响应,将客户端重定向到指定的 URL。
主要作用
-
设置响应状态码:例如,设置 200 表示成功,404 表示资源未找到,500 表示服务器内部错误。
-
设置响应头:例如,设置 Content-Type 指定响应体的 MIME 类型,设置 Content-Disposition 触发文件下载。
-
写入响应体:通过输出流向客户端发送数据(如 HTML、JSON、文件等)。
-
重定向和错误处理:例如,将客户端重定向到另一个 URL,或返回错误页面。
用于下载文件
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.beans.Encoder;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Base64;
public class download extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取上下文
ServletContext servletContext = this.getServletContext();
// 获取文件实际在磁盘中的位置, 这个方法将Web 应用中的相对路径转换为服务器文件系统上的实际路径。
String path = servletContext.getRealPath("/WEB-INF/classes/vertin.jpg");
// 获取文件名
String filename = path.substring(path.lastIndexOf("/") + 1);
// 设置响应头,告知浏览器这个响应是一个文件下载
resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
// 获取输入流
FileInputStream fileInputStream = new FileInputStream(path);
byte[] bytes = new byte[fileInputStream.available()];
int len;
// 获取输出流
ServletOutputStream outputStream = resp.getOutputStream();
while((len = fileInputStream.read(bytes)) != -1){
outputStream.write(bytes, 0, len);
}
fileInputStream.close();
outputStream.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
给浏览器发送Image对象
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
public class image extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 让浏览器3秒自动刷新一次
resp.setHeader("refresh", "3");
// 在内存中创建一个图片
BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
// 得到图片
Graphics g = image.getGraphics();
g.setColor(Color.GRAY);
g.fillRect(0, 0, 200, 200);
// 给图片中写入数字
g.setColor(Color.BLACK);
g.setFont(new Font("Times New Roman", Font.PLAIN, 20));
g.drawString(getNum(), 50, 50);
// 告诉浏览器,响应用图片的方式打开
resp.setContentType("image/jpeg");
// 网站存在缓存,不让浏览器缓存
resp.setDateHeader("Expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "No-cache");
// 将图片发给浏览器
ImageIO.write(image, "jpeg", resp.getOutputStream());
}
private String getNum() {
String num = new Random().nextInt(999999) + "";
if(num.length() != 6){
while(num.length() < 6){
num = "0" + num;
}
}
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
结合重定向完成用户登录跳转的效果
- 导入包
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
- 在index.jsp中添加登录按钮
<%--
Created by IntelliJ IDEA.
User: zzl
Date: 2025/2/11
Time: 19:29
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--这里${pageContext.request.contextPath}表示web项目--%>
<form action="${pageContext.request.contextPath}\login" method="get">
用户名:<input type="text" name="username">
密码:<input type="password" name="password"></input>
<input type="submit">
</form>
</body>
</html>
- 完成LoginServlet
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取用户名的登录名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + " " + password);
// 重定向到刚刚写的图片程序
resp.sendRedirect("/servlet_context_war_exploded/image");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 配置web.xml
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.myLearning.login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
HttpServletRequest类
HttpServletRequest 是 Java Servlet API 中的一个核心接口,用于表示客户端的 HTTP 请求。它提供了访问请求信息(如参数、头、URL、会话等)的方法,使开发者能够处理客户端发送的数据并作出相应的响应。
主要作用
-
获取请求参数:从 URL 查询字符串或表单数据中获取参数。
-
获取请求头:读取客户端发送的 HTTP 头信息(如 User-Agent、Content-Type 等)。
-
获取请求路径和 URL:获取请求的 URL、URI、上下文路径等信息。
-
获取会话信息:获取或创建与客户端关联的会话(HttpSession)。
-
获取请求体数据:读取客户端发送的请求体数据(如表单数据、JSON 数据等)。
-
获取客户端信息:获取客户端的 IP 地址、主机名等信息。
-
转发和重定向:将请求转发到其他资源或重定向到其他 URL。
常用方法
-
getParameter(String name):获取指定名称的请求参数值。
-
getHeader(String name):获取指定名称的请求头值。
-
getMethod():获取请求的 HTTP 方法(如 GET、POST 等)。
-
getRequestURI():获取请求的 URI。
-
getContextPath():获取请求的上下文路径。
-
getSession():获取与请求关联的会话对象。
-
getRemoteAddr():获取客户端的 IP 地址。
-
setAttribute(String name, Object o):设置请求属性。
-
getAttribute(String name):获取请求属性。
-
getRequestDispatcher(String path):获取用于请求转发的 RequestDispatcher 对象。
-
sendRedirect(String location):重定向到指定 URL。
获取参数以及转发
package com.myLearning;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取用户名的登录名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + " " + password);
// 转发
req.getRequestDispatcher("/image");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Cookie类
Cookie 并不是它的原意“甜饼”的意思, 而是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web 文档关联在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用。由于“Cookie”具有可以保存在客户机上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能, 而这一切都不必使用复杂的CGI等程序。
Cookie类的常用方法
public Cookie(String name,String value)
: 创建一个Cookie对象public String getName()
: 获取Cookie的名称public String getValue()
: 获取Cookie的值public void setMaxAge(int expiry)
: 设置Cookie的有效期, 以秒为单位, 默认有效期为当前session有效期内public void setPath(String uri)
: 设置Cookie的路径public void setDomain(String pattern)
: 设置Cookie的域名public void addCookie(Cookie cookie)
: 添加Cookie到响应中public Cookie[] getCookies()
: 获取请求中的所有Cookie
Session类
Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。
Session类的主要作用
- 在不同请求之间传递数据, 将数据保存在服务器端
- 实现跨请求的数据共享
Session类的常用方法
public String getId()
: 获取Session的IDpublic void setAttribute(String name, Object value)
: 设置Session属性public Object getAttribute(String name)
: 获取Session属性public void removeAttribute(String name)
: 移除Session属性public void invalidate()
: 销毁Sessionpublic long getCreationTime()
: 获取Session创建时间public long getLastAccessedTime()
: 获取Session最后访问时间public int getMaxInactiveInterval()
: 获取Session最大不活动时间public void setMaxInactiveInterval(int interval)
: 设置Session最大不活动时间public ServletContext getServletContext()
: 获取ServletContext对象
Session的生命周期
- 创建: 当客户端第一次访问某个Servlet或JSP时, 服务器会为该客户端创建一个Session对象
- 销毁: Session对象在以下情况下会被销毁:
- 调用
invalidate()
方法 - Session过期: 默认情况下, Session在30分钟后过期. 可以通过
setMaxInactiveInterval(int interval)
方法设置Session的最大不活动时间 - 服务器关闭
- 在web.xml文件中配置Session的过期时间
- 调用
示例
给Session对象添加属性
package com.myLearning;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
public class SessionSet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
// 获取Session对象
HttpSession session = req.getSession(true);
// 给Session对象添加属性
session.setAttribute("likes","panda");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
从Session对象中获取属性
package com.myLearning;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
public class SessionGet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
// 获取Session对象
HttpSession session = req.getSession(true);
// 获取Session对象中的属性
String likes = (String) session.getAttribute("likes");
resp.getWriter().print(likes);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
JSP
JSP是什么?
JSP(JavaServer Pages)是一种用于创建动态网页的技术,允许开发者在HTML中嵌入Java代码。以下是其关键点:
定义
JSP是Java EE的一部分,用于构建动态Web内容。
工作原理
JSP文件在服务器上被编译为Servlet。Servlet生成HTML并发送给客户端。
主要特点
嵌入Java代码:通过<% %>标签嵌入Java代码。标签库:支持JSTL等标签库,简化开发。组件重用:可通过JavaBeans和自定义标签实现组件复用。
优点
- 分离逻辑与表现:便于维护。
- 跨平台:基于Java,可在任何支持Java的平台上运行。
- 强大API:提供丰富的API支持复杂应用。
缺点
- 复杂性:相比PHP等语言,学习曲线较陡。
- 性能开销:首次请求时需编译,可能影响性能。
JSP以及JSPL依赖包导入
<dependencies>
<!-- 使用 Jakarta Servlet API -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<!-- 使用 Jakarta JSTL API -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.2</version>
</dependency>
<!-- JSTL 实现 -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
注意:需要手动在tomcat的lib目录下添加jakarta.servlet.jsp.jstl-api和jakarta.servlet.jsp.jstl两个jar包,否则可能会报ClassNotFound的错误。
JSP基本语法
JSP脚本元素
声明
<%! declaration; %>
用于声明全局变量、方法等。
表达式
<%= expression %>
用于输出表达式的结果。
代码块
<% code %>
用于嵌入Java代码。
示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%!
private static String globalVarStr = "看我,我是类中的变量!";
private void fun(){
System.out.println("这里是类中的方法");
}
%>
<hr>
<%
for(int i = 0;i < 10;++i){
out.println("在这里可以编写Java代码");
}
%>
<hr>
<%= new String("这里的变量会直接输出喔~")%>
</body>
</html>
JSP指令
page指令
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
用于设置JSP页面的属性,如内容类型、字符编码、脚本语言等。
include指令
<%@ include file="included.jsp" %>
用于将一个JSP页面包含到另一个JSP页面中。
taglib指令
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
用于引入JSTL标签库。
errorPage指令
<%@ page errorPage="error.jsp" %>
用于指定错误页面。
与此同时,还可以在web.xml
中配置错误页面:
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
isErrorPage指令
<%@ page isErrorPage="true" %>
用于指定当前页面是否为错误页面。
JSP内置对象及对应的常用方法
JSP内置对象
JSP内置对象是JSP页面中可以直接使用的对象,无需显式声明。JSP内置对象包括:
- request:表示客户端的请求,包含了客户端请求的所有信息。
- response:表示服务器端的响应,用于向客户端发送响应数据。
- session:表示客户端与服务器之间的会话,用于保存客户端的状态信息。
- application:表示整个Web应用程序,用于保存全局共享的数据。
- out:表示服务器端的输出流,用于向客户端输出数据。
- pageContext:表示当前页面的上下文,用于访问其他JSP内置对象。
- config:表示当前JSP页面的配置信息,如初始化参数等。
- page:表示当前JSP页面的实例,用于访问当前页面的属性和方法。
- exception:表示当前页面发生的异常,用于处理异常情况。
request对象常用方法
String getParameter(String name)
:获取指定名称的请求参数的值。String[] getParameterValues(String name)
:获取指定名称的请求参数的所有值。Map<String, String[]> getParameterMap()
:获取所有请求参数的键值对。String getHeader(String name)
:获取指定名称的请求头的值。void setAttribute(String name, Object value)
:设置指定名称的请求属性。Object getAttribute(String name)
:获取指定名称的请求属性的值。String getRemoteAddr()
:获取客户端的IP地址。String getContextPath()
:获取当前Web应用的上下文路径。String getServletPath()
:获取当前JSP页面的Servlet路径。
session对象常用方法
void setAttribute(String name, Object value)
:设置指定名称的会话属性的值。Object getAttribute(String name)
:获取指定名称的会话属性的值。void removeAttribute(String name)
:移除指定名称的会话属性。String getId()
:获取会话ID。
application对象常用方法
void setAttribute(String name, Object value)
:设置指定名称的全局共享数据的值。Object getAttribute(String name)
:获取指定名称的全局共享数据的值。void removeAttribute(String name)
:移除指定名称的全局共享数据。
out对象常用方法
void println(String s)
:向客户端输出字符串。void flush()
:刷新输出流。void close()
:关闭输出流。
pageContext对象常用方法
Object getAttribute(String name)
:获取指定名称的属性值。void setAttribute(String name, Object value)
:设置指定名称的属性值。void forward(String url)
:转发到指定的URL。void include(String url)
:包含指定的URL。HttpSession getSession()
:获取当前会话对象。ServletContext getServletContext()
:获取当前Web应用的ServletContext对象。
config对象常用方法
String getInitParameter(String name)
:获取指定名称的初始化参数的值。ServletContext getServletContext()
:获取当前Web应用的ServletContext对象。
exception对象常用方法
String getMessage()
:获取异常的详细消息。String getLocalizedMessage()
:获取异常的本地化消息。String toString()
:获取异常的字符串表示。void printStackTrace()
:打印异常的堆栈跟踪信息。
page对象常用方法
void forward(String url)
:转发到指定的URL。void include(String url)
:包含指定的URL。Object getSession()
:获取当前会话对象。ServletContext getServletContext()
:获取当前Web应用的ServletContext对象。
简单示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
This is just an index page!
<%
session.setAttribute("name","vertin");
%>
<hr>
<%= session.getAttribute("name") %>
</body>
</html>
JSP标签
JSP动作标签
JSP动作标签是JSP 1.2引入的一种特殊标签,用于在JSP页面中执行特定的操作。JSP动作标签以<jsp:
开头,并且没有结束标签。
常用JSP动作标签
<jsp:include>
:用于包含另一个JSP页面。<jsp:forward>
:用于转发请求到另一个资源。<jsp:param>
:用于传递参数给包含或转发的资源。<jsp:useBean>
:用于实例化JavaBean对象。<jsp:setProperty>
:用于设置JavaBean对象的属性值。<jsp:getProperty>
:用于获取JavaBean对象的属性值。<jsp:plugin>
:用于在JSP页面中嵌入Java小程序。<jsp:element>
:用于动态创建XML元素。<jsp:attribute>
:用于动态创建XML元素的属性。<jsp:text>
:用于在JSP页面中嵌入纯文本内容。
简单示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
This is just an index page!
<jsp:include page="include.jsp"></jsp:include>
<hr>
<jsp:forward page="forward.jsp"></jsp:forward>
</body>
</html>
JSP标准标签库(JSTL)
JSTL(JavaServer Pages Standard Tag Library)是一个JSP标签库,用于简化JSP页面的开发。JSTL包含以下几部分:
- Core标签:用于执行常见的JSP操作,如条件判断、循环、国际化等。Core标签以
<c:
开头。 - I18N标签:用于处理国际化(i18n)相关的操作,如格式化日期、数字和消息等。I18N标签以
<fmt:
开头。 - SQL标签:用于执行SQL查询和操作。SQL标签以
<sql:
开头。 - XML标签:用于处理XML数据。XML标签以
<x:
开头。 - Functions标签:用于定义自定义函数。Functions标签以
<fn:
开头。
常用JSTL标签
<c:if>
:用于条件判断。<c:choose>
、<c:when>
、<c:otherwise>
:用于多条件判断。<c:forEach>
:用于循环遍历集合。<c:forTokens>
:用于按分隔符分割字符串并循环遍历。<c:out>
:用于输出变量或表达式的值。<c:set>
:用于设置变量的值。<c:remove>
:用于移除变量。
简单示例
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:set var="myVar" value="hahahah"/>
<c:out value="${myVar}"/>
<%
ArrayList<Integer> hairNumArr = new ArrayList<Integer>();
hairNumArr.add(1);
hairNumArr.add(2);
hairNumArr.add(3);
hairNumArr.add(4);
hairNumArr.add(5);
request.setAttribute("hairNumArr",hairNumArr);
%>
<hr>
<c:set var="i" value="1"/>
<c:forEach items="${hairNumArr}" var="hair" begin="0" end="4" step="1">
<c:out value="第${i}个程序猿头发的数量为${hair}"/> <hr>
<c:set var="i" value="${i + 1}"/>
</c:forEach>
</body>
</html>
EL表达式
EL表达式用于在JSP页面中获取数据,类似于JSTL标签。EL表达式以${}
开头,可以访问JavaBean的属性、集合、数组等。
常用EL表达式
${param.name}
:获取请求参数name的值。${requestScope.name}
:获取请求作用域中name的值。${sessionScope.name}
:获取会话作用域中name的值。${applicationScope.name}
:获取应用作用域中name的值。${pageScope.name}
:获取页面作用域中name的值。${initParam.name}
:获取web.xml中配置的初始化参数name的值。${cookie.name}
:获取名为name的cookie的值。${pageContext.request.contextPath}
:获取当前web应用的上下文路径。
EL表达式运算符
- 算术运算符:
+
、-
、*
、/
、%
- 比较运算符:
==
、!=
、>
、<
、>=
、<=
- 逻辑运算符:
&&
、||
、!
- 条件运算符:
? :
- 其他运算符:
empty
、not empty
、[]
、()
等
EL表达式运算符示例
<%
int a = 10;
int b = 20;
request.setAttribute("a", a);
request.setAttribute("b", b);
%>
<hr>
${a + b} <hr>
${a - b} <hr>
${a * b} <hr>
${a / b} <hr>
${a % b} <hr>
<hr>
${a > b} <hr>
${a < b} <hr>
${a >= b} <hr>
${a <= b} <hr>
${a == b} <hr>
${a != b} <hr>
JavaBean类
JavaBean是一种符合特定规范的Java类,通常用于封装数据。JavaBean类通常具有以下特点:
- 类必须具有一个无参的构造方法。
- 类中的属性通常使用private修饰符进行封装。
- 类中提供对应的getter和setter方法用于访问和修改属性。
- 类中可以包含一些业务逻辑方法。
JavaBean类通常用于封装数据,例如用户信息、订单信息等。在JSP页面中,可以通过EL表达式或JSTL标签来访问JavaBean类的属性和方法。
JavaBean类示例
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
简述MVC三层架构
MVC(Model-View-Controller)是一种软件设计模式,用于将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller)。MVC模式的主要目的是将应用程序的逻辑与表示分离,以提高代码的可维护性和可扩展性。
在MVC模式中,模型(Model)负责处理应用程序的数据和业务逻辑。模型通常包含一个或多个JavaBean类,用于封装数据。模型还负责与数据库或其他数据源进行交互,以获取和存储数据。
视图(View)负责显示应用程序的用户界面。视图通常是一个JSP页面,用于显示模型中的数据。视图还负责处理用户输入,并将其传递给控制器。
控制器(Controller)负责处理用户请求,并将请求转发给适当的模型和视图。控制器通常是一个Servlet或Action类,用于接收用户请求,调用模型中的方法,并将结果传递给视图。
在MVC模式中,用户通过视图与应用程序进行交互。用户在视图中输入数据,然后控制器接收请求,并将请求转发给模型。模型处理请求,并将结果返回给控制器。控制器将结果传递给视图,视图将结果显示给用户。
filter过滤器
在Java Web应用程序中,过滤器(Filter)是一种特殊的Java类,用于拦截客户端请求和响应,并对请求和响应进行处理。过滤器可以用于实现各种功能,例如身份验证、日志记录、数据压缩等。
过滤器通过实现javax.servlet.Filter接口来创建。Filter接口定义了三个方法:init()、doFilter()和destroy()。
-
init()方法在过滤器初始化时调用,用于初始化过滤器。该方法接收一个FilterConfig对象作为参数,该对象包含过滤器的配置信息。
-
doFilter()方法在每次请求和响应时调用,用于处理请求和响应。该方法接收一个ServletRequest、ServletResponse和FilterChain对象作为参数。ServletRequest和ServletResponse对象用于获取请求和响应的信息,FilterChain对象用于将请求传递给下一个过滤器或目标资源。
-
destroy()方法在过滤器销毁时调用,用于释放过滤器占用的资源。
过滤器可以通过在web.xml文件中配置来使用。在web.xml文件中,可以使用和元素来定义过滤器及其映射规则。
使用过滤器
1. 创建一个类实现Filter接口
package com.Filter;
import jakarta.servlet.*;
import java.io.IOException;
public class Filter01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
chain.doFilter(request, response); // 将请求传递给下一个过滤器或目标资源
}
}
2. 在web.xml文件中配置过滤器
<filter>
<filter-name>filter01</filter-name>
<filter-class>com.Filter.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>filter01</filter-name> <!-- 与filter标签中的filter-name一致 -->
<url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>
JavaWeb中的listener监听器
监听器是JavaWeb中的一种特殊类,用于监听JavaWeb中的各种事件,如Servlet的创建和销毁、Session的创建和销毁、请求的到达和结束等。监听器可以用于实现一些特殊的功能,如统计网站的访问量、记录用户的登录信息等。
1. 监听器的基本使用
1.1 创建监听器类
package com.com.Listenner;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
public class Listenner01 implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
Integer count = (Integer)se.getSession().getServletContext().getAttribute("SessionCount");
if(count == null){
se.getSession().getServletContext().setAttribute("SessionCount", 1);
}else {
se.getSession().getServletContext().setAttribute("SessionCount", ++count);
}
}
public void sessionDestroyed(HttpSessionEvent se) {
Integer count = (Integer)se.getSession().getServletContext().getAttribute("SessionCount");
se.getSession().getServletContext().setAttribute("SessionCount", --count);
}
}
1.2 在web.xml中配置监听器
<listener>
<listener-class>com.com.Listenner.Listenner01</listener-class>
</listener>
笔记总结于视频:https://www.bilibili.com/video/BV12J411M7Sj?vd_source=16bf0c507e4a78c3ca31a05dff1bee4e&spm_id_from=333.788.videopod.episodes