Servlet
Servlet简介
- Servlet就是sun公司开发动态web的一门技术
- Sun在这些API中提供一个接口叫做:Servlet
- 开发一个Servlet的步骤:
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器中。
把实现了Servlet接口的Java程序叫做,Servlet
开发一个servlet
Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
创建干净的maven项目
这个作为Maven的主程序,可以在里面创建带有Maven模板的子模块
- 删除src文件夹

去Maven仓库找必要的API


- 导入Maven依赖

- 将限定范围删除

创建servlet项目的web子程序
创建子模块module
- 在当前大web项目里创建子工程

- 带Maven模板的

- 子工程项目名

- 创建成功

- 更换最新的web.xml的版本
- 老:

- 新:

<?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"
metadata-complete="true">
</web-app>
这里建议在大项目的文件夹里创建一个note_webXml文件,用于存放新版的xml,每次创建子程序的时候可以直接复制粘贴

- 将Maven项目构建完整
- 创建源码目录和资源目录

- ctrl + o 调出重写框

package com.feifan.sevlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.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.print("Hello, Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
编写Servlet的映射
- 在子模块的web.xml内编写
在下列文件内添加程序

- 编写程序
<servlet>
<servlet-name>......</servlet-name>
<servlet-class>......</servlet-class> <!-- 注册的类-->
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>......</servlet-name> <!-- 与上面的name对应-->
<url-pattern>......</url-pattern> <!-- 请求路径-->
</servlet-mapping>
- 编写完成

配置Tomcat
- 增加配置 add Configuration
-
注意add artifact
-
一样的名字

-
这个框中输入
/或者/所在子模块文件名
-
-
Tomcat成功

- Servlet成功!
Servlet原理

映射问题(Mapping)
- 一个Servlet指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 一个Servlet指定多个映射路径
<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>/hello3</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello5</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
- 默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 指定一些后缀或者前缀等等
<!--可以自定义后缀实现请求映射
注意点,*前面不能加项目映射的路径
hello/sajdlkajda.qinjiang -->
<servlet-mapping>
<servlet-name>hello</servlet-name> <url-pattern>*.qinjiang</url-pattern> </servlet-mapping>
- 优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的 web应用
作用:
共享数据
两个Servlet(Java文件)获取同样的信息
- 通过第三方读取文件(不推荐)

- 用ServletContext对象

1)创建两个Servlet
- 写入数据的Servlet
package com.feifan.servlet;
import javax.servlet.ServletContext;
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 GetServletContext extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc = this.getServletContext();
String username = (String) sc.getAttribute("username");
resp.getWriter().print("名字:" + username);
}
}
- 读取数据的Servlet
package com.feifan.servlet;
import javax.servlet.ServletContext;
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 HelloServletContext extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc = this.getServletContext();
String username = "pff";
sc.setAttribute("username",username); //用键值对的方式将用户名放入Servlet Context
}
}
2)注意中文的编码格式
-
没有先hello设置username
也没有设置编码格式
3)先访问/hello 设置uesrname

4)然后再访问 /getC 获取ServletContext

获取初始化参数
- 在子模版的web.xml内进行配置参数

<!-- 配置web的一些初始化参数-->
<context-param>
<param-name>url</param-name>
<!--这里是数据库的一个参数,以后用得上-->
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
- doGet方法中进行获取
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc = this.getServletContext();
String url = sc.getInitParameter("url");
resp.getWriter().print(url);
}
- 成功获取

请求转发操作
进入一个Servlet时,转发到另外一个Servlet中去
- 在HelloServletContext类中(对应的是/hello)
编写请求转发
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc = this.getServletContext();
System.out.println("进入了HelloServletContext");
//RequestDispatcher requestDispatcher = sc.getRequestDispatcher("/getC"); //声明请求的路径
//requestDispatcher.forward(req,resp); //进行转发的操作
sc.getRequestDispatcher("/getC").forward(req,resp);
}
运行时还是先进的HelloServletContext
- 运行完了输入 /hello
跳转到 /get 的界面中去

总结转发思路:
A要找C,转发 路径不发生改变

重定向 路径发生改变

读取资源文件
Properties
- 在java目录下新建
.properties文件 - 在resources目录下新建
.properties文件
结果:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath类路径
-->通过文件流的方式读取资源文件的信息
- 创建一个getProperties的Servlet
package com.feifan.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class GetProperties extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过context拿到properties,并把资源变成一个流
//第一个 '/' 代表当前的web项目,不能省略
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
//将资源流进行加载,并获得其中的属性
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user + ":" + pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 增加映射
<servlet>
<servlet-name>getP</servlet-name>
<servlet-class>com.feifan.servlet.GetProperties</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getP</servlet-name>
<url-pattern>/getP</url-pattern>
</servlet-mapping>
- 运行成功,成功获取资源文件信息

问题:无法获取Java文件下的
maven由于他的约定大于配置,所以我们写的配置文件,无法被导出或者生效解决办法:在子模块的pom.xml里进行
build配置resources,来防止我们资源导出失败的问题
<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>
进行测试:
- getProperties的Servlet文件
注意这里路径一定要完整
public class GetProperties extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过context拿到properties,并把资源变成一个流
//第一个 '/' 代表当前的web项目,不能省略
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/feifan/servlet/feifan.properties");
//将资源流进行加载,并获得其中的属性
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user + ":" + pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
-
映射
-
运行成功

请求、响应对象
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
HttpServletResponse类
结构
- 向浏览器发送数据的方法
// 输出一个流
ServletOutputStream getOutputStream() throws IOException;
// 普通的字符串,如果是中文的话要配置编码格式
PrintWriter getWriter() throws IOException;
- 向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
- 响应 的状态码
int SC_OK = 200;
int SC_MULTIPLE_CHOICES = 300;
int SC_BAD_REQUEST = 400
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;
应用
通过浏览器输出消息
getOutputStream();
getWriter()
下载文件
1)获取下载文件的路径
2)设置下载后文件的名字
3)设置浏览器能够支持下载我们需要的东西
4)获取下载文件输入流
5)创建缓冲区
6)获取OutputStream的对象
7)将FileOutputStream流写入buffer缓冲区
8)使用OutputStream将缓冲的数据输出到客户端
Servlet文件:
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 要获取下载文件的路径,这里用绝对路径
String realPath = "E:\\Programing\\Java\\Web\\Servlet\\kuangTest\\req_resp\\src\\main\\resources\\入海.png";
System.out.println("下载文件的路径:" + realPath);
// 2. 下载的文件名是啥?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西
// 中文文件 名URLEncoder.encode编码,否则下载的文件名有可能乱码
// 浏览器行为用resp对象
resp.setHeader("Content-Disposition"," attachment; filename = "+ URLEncoder.encode(fileName,"UTF-8"));
// 4. 获取下载文件的输入流
// 将文件路径变成流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区
// 8. 使用OutputStream将缓冲区中的数据 输出到客户端!
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
映射:
<servlet>
<servlet-name>reqresp</servlet-name>
<servlet-class>FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>reqresp</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
- 运行成功
验证码功能
- 前端实现
用JS去进行判断 - 后台实现
运用Java的图片类,生成一个图片
Servlet文件
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器5秒刷新一次
resp.setHeader("refresh", "3");
// 在内存中创建图片
// BufferedImage.TYPE_INT_RGB是三原色
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
// 得到内存的图片
Graphics2D gra = (Graphics2D) image.getGraphics(); // 画笔进行操作
//设置图片背景颜色
gra.setColor(Color.white); //颜色填充,白色的背景
gra.fillRect(0, 0, 80, 20);
//给图片写数据
gra.setColor(Color.BLUE); // 选择蓝色的进行书写
gra.setFont(new Font(null, Font.BOLD, 20)); // BOLD粗体
gra.drawString(makeNum(), 0, 20); // 在(0,20)的位置吧随机数画上去
// 告诉浏览器这个请求用图片的方式打开
resp.setContentType("image/jpeg");
// 网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires", -1); // 不让缓存
resp.setHeader("Cache-Control", "no-cache"); // 缓存控制设置为不缓存
resp.setHeader("Pragma", "no-cache");
// 把图片写给浏览器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
//生成随机数
private String makeNum() {
Random random = new Random(); //随机数对象
String num = random.nextInt(9999999) + ""; // 转成字符串
StringBuffer sb = new StringBuffer(); // 可变长的字符串
// 如果不够7位数的 用0在前面进行填充
for (int i = 0; i < 7 - num.length(); i++) {
sb.append("0");
}
num = sb.toString() + num; // 字符串连接
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

重定向
概念:
一个web资源B收到客户端A请求后,B会通知A客户端去访问另外一个web资源C
图解:

场景:
用户登录,成功之后会跳转
实现方法:
void sendRedirect(String var1) throws IOException;
简单实现:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/response/image");
}
注意这里面的跳转之前的web地址应该和Tomcat中配置的一样
重定向和转发的区别:
-
相同点
页面都会实现跳转
-
不同点
- 请求转发的时候,url不会产生变化
- 重定向时候,url地址栏会发生变化
HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器
HTTP请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest对象的方法,获得客户端的所有信息;
获取请求 行 信息的方法
访问 Servlet 时,所有请求消息将被封装到 HttpServletRequest 对象中,请求消息的请求行中包含 请求方法、请求资源名、请求路径 等信息
| 方法声明 | 功能描述 |
|---|---|
| String getMethod() | 该方法用于获取 HTTP 请求消息中的请求方式(如 GET、POST 等) |
| String getRequestURI() | 该方法用于获取请求行中的资源名称部分即位于 URL 的主机和端门之后、参数部分之前的部分 |
| String getQueryString() | 该方法用于获取请求行中的参数部分,也就是资源路径后问号(?)以后的所有内容 |
| String getContextPath() | 该方法用于获取请求 URL 中属于 Web 应用程序的路径,这个路径以 / 开头,表示相对于整个 Web 站点的根目录,路径结尾不含 /。如果请求 URL 属于 Web 站点的根目录,那么返回结果为空字符串("") |
| String getServletPath() | 该方法用于获取 Servlet 的名称或 Servlet 所映射的路径 |
| String getRemoteAddr() | 该方法用于获取请求客户端的 IP 地址,其格式类似于 192.168.0.3 |
| String getRemoteHost() | 该方法用于获取请求客户端的完整主机名,其格式类似于 pcl.mengma.com。需要注意的是,如果无法解析出客户机的完整主机名,那么该方法将会返回客户端的 IP 地址 |
| int getRemotePort() | 该方法用于获取请求客户端网络连接的端口号 |
| String getLocaIAddr() | 该方法用于获取 Web 服务器上接收当前请求网络连接的 IP 地址 |
| String getLocalName() | 该方法用于获取 Web 服务器上接收当前网络连接 IP 所对应的主机名 |
| int getLocalPort() | 该方法用于获取 Web 服务器上接收当前网络连接的端口号 |
| String getServerName() | 该方法用于获取当前请求所指向的主机名,即 HTTP 请求消息中 Host 头字段所对应的主机名部分 |
| int gctServcrPort() | 该方法用于获取当前请求所连接的服务器端口号,即 HTTP 请求消息中 Host 头字段所对应的端口号部分 |
| StringBuffcr getRequestURL() | 该方法用于获取客户端发出请求时的完整 URL,包括协议、服务器名、端口号、 资源路径等信息,但不包括后面的査询参数部分。注意,getRequcstURL() 方法返冋的结果是 StringBuffer 类型,而不是 String 类型,这样更便于对结果进行修改 |
获取请求消息头的方法
当浏览器发送 Servlet 请求时,需要通过请求消息头向服务器传递附加信息,例如,客户端可以接收的 数据类型、压缩方式、语言 等
| 方法声明 | 功能描述 |
|---|---|
| String getHeader(String name) | 该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,则 getHeader() 方法返回 null;如果请求消息中包含多个指定名称的头字段,则 getHeader() 方法返回其中第一个头字段的值 |
| Enumeration getHeaders(String name) | 该方法返回一个 Enumeration 集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成。在多数情况下,一个头字段名在请求消息中只出现一次,但有时可能会出现多次 |
| Enumeration getHeaderNames() | 该方法用于获取一个包含所有请求头字段的 Enumeration 对象 |
| int getIntHeader(String name) | 该方法用于获取指定名称的头字段,并且将其值转为 int 类型。需要注意的是,如果指定名称的头字段不存在,则返回值为 -1;如果获取到的头字段的值不能转为 int 类型,则将发生 NumberFormatException 异常 |
| long getDateHeader(String name) | 该方法用于获取指定头字段的值,并将其按 GMT 时间格式转换为一个代表日期/时间的长整数,该长整数是自 1970 年 1 月 1 日 0 时 0 分 0 秒算起的以毫秒为单位的时间值 |
| String getContentType() | 该方法用于获取 Content-Type 头字段的值,结果为 String 类型 |
| int getContentLength() | 该方法用于获取 Content-Length 头字段的值,结果为 int 类型 |
| String getCharacterEncoding() | 该方法用于返回请求消息的实体部分的字符集编码,通常是从 Content-Type 头字段中进行提取,结果为 String 类型 |
应用(用户登录)
获取参数 + 请求转发

Servlet文件
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
// 通过getParameterValues获取多选框对应的多个值
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("============================="); //后台接收中文乱码问题
System.out.println(username);
System.out.println(password);
// 打印数组
System.out.println(Arrays.toString(hobbys));
System.out.println("=============================");
//通过请求转发
//这里的 / 代表当前的web应用
req.getRequestDispatcher("/success.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
index.jsp
<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆界面</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
爱好:
<input type="checkbox" name="hobby" value="看书">看书
<input type="checkbox" name="hobby" value="代码">代码
<input type="checkbox" name="hobby" value="游戏">游戏
<br>
<input type="submit">
</form>
</body>
</html>
success.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021-04-07
Time: 7:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆成功</title>
</head>
<body>
<h1>登陆成功</h1>
</body>
</html>
web.xml里的映射
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
Cookie
概述
Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。
识别返回用户包括三个步骤:
- 服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。
- 浏览器将这些信息存储在本地计算机上,以备将来使用。
- 当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。
操作 Cookie 的方法
获得Cookie对象:
Cookie[] cookies = req.getCookies();
| 方法 | 描述 |
|---|---|
| public void setDomain(String pattern) | 该方法设置 cookie 适用的域 |
| public String getDomain() | 该方法获取 cookie 适用的域,例如 runoob.com。 |
| public void setMaxAge(int expiry) | 该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。 |
| public int getMaxAge() | 该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。 |
| public String getName() | 该方法返回 cookie 的名称。名称在创建后不能改变。 |
| public void setValue(String newValue) | 该方法设置与 cookie 关联的值。 |
| public String getValue() | 该方法获取与 cookie 关联的值。 |
| public void setPath(String uri) | 该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。 |
| public String getPath() | 该方法获取 cookie 适用的路径。 |
| public void setSecure(boolean flag) | 该方法设置布尔值,表示 cookie 是否应该只在加密的(即 SSL)连接上发送。 |
| public void setComment(String purpose) | 设置cookie的注释。该注释在浏览器向用户呈现 cookie 时非常有用。 |
| public String getComment() | 获取 cookie 的注释,如果 cookie 没有注释则返回 null。 |
设置 Cookie
步骤:
- 创建一个 Cookie 对象
调用带有 cookie 名称和 cookie 值的 Cookie 构造函数,cookie 名称和 cookie 值都是字符串。
Cookie cookie = new Cookie("key","value");
中文数据的传输:
// 编码
Cookie cookie = new Cookie("name", URLEncoder.encode("大帅哥","utf-8"));
// 解码
out.write(URLDecoder.decode(cookie.getValue(),"UTF-8"));
- 设置最大生存周期
使用 setMaxAge 方法来指定 cookie 能够保持有效的时间(以秒为单位)。
设置一个最长有效期为 24 小时的 cookie:
cookie.setMaxAge(60*60*24);
- 发送 Cookie 到 HTTP 响应头
使用 response.addCookie 来添加 HTTP 响应头中的 Cookie
response.addCookie(cookie);
应用
通过cookie保存上一次访问浏览器的时间
- Servlet文件
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
public class CookieOpera extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-16");
req.setCharacterEncoding("utf-16");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
if (cookies != null) {
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals("lastLoginTime")){
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是你第一次访问");
}
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- web.xml里的映射
<servlet>
<servlet-name>CookieOpera</servlet-name>
<servlet-class>CookieOpera</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieOpera</servlet-name>
<url-pattern>/co</url-pattern>
</servlet-mapping>
- 第一次运行
时间没有进行输出,而是先设置在cookie当中
找到cookie,发现里面有请求的键值对
- 进行刷新,出现时间
Session
介绍
概念:
Servlet提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时 识别用户 以及 存储有关用户信息 的方式。
使用HttpSession 接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。
会话持续一个指定的时间段,跨多个连接或页面请求。
特点:
- 服务器会给每一个用户(浏览器)创建一个Seesion对象
- 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登录之后,整个网站它都可以访问
Session和cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
- Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
- Session对象由服务器创建
方法
通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象
HttpSession session = request.getSession();
| 方法 | 描述 |
|---|---|
| public Object getAttribute(String name) | 该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。 |
| public Enumeration getAttributeNames() | 该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。 |
| public long getCreationTime() | 该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
| public String getId() | 该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。 |
| public long getLastAccessedTime() | 该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
| public int getMaxInactiveInterval() | 该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。 |
| public void invalidate() | 该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。 |
| public boolean isNew() | 如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。 |
| public void removeAttribute(String name) | 该方法将从该 session 会话移除指定名称的对象。 |
| public void setAttribute(String name, Object value) | 该方法使用指定的名称绑定一个对象到该 session 会话。 |
| public void setMaxInactiveInterval(int interval) | 该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。 |
例子
获取Session的ID
在每次访问浏览器时,都会自动创建Session对象
里面包含了SessionID
- Servlet文件
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class GetSessionId extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
// 获取Session的ID
String sessionId = session.getId(); //判断Session是不是新创建
if (session.isNew()) {
resp.getWriter().write("session创建成功,ID:" + sessionId);
} else {
resp.getWriter().write("session以及在服务器中存在 了,ID:" + sessionId);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- web.xml映射
<servlet>
<servlet-name>GetSessionId</servlet-name>
<servlet-class>GetSessionId</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetSessionId</servlet-name>
<url-pattern>/gsi</url-pattern>
</servlet-mapping>
- 运行成功

获取Session中的设置的参数
普通类型和对象都可以设置和接收
- 设置
- Servlet文件
package com.feifan;
import com.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SetSessionAttribute extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
// 1.普通类型
session.setAttribute("name", "大帅哥");
// 2.对象
session.setAttribute("person", new Person("大帅哥", 666));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- web.xml映射
<servlet>
<servlet-name>SetSessionAttribute</servlet-name>
<servlet-class>com.feifan.SetSessionAttribute</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SetSessionAttribute</servlet-name>
<url-pattern>/ssa</url-pattern>
</servlet-mapping>
- 获取
- Servlet文件
package com.feifan;
import com.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class GetSessionAttribute extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
String name = (String) session.getAttribute("name");// 得到name对应的大帅哥
System.out.println(name); // 在后台进行输出
Person person = (Person) session.getAttribute("person");// 得到name对应的对象
System.out.println(person.toString()); // 调用对象里重写过的toString方法
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 进行操作
- 设置

- 获取

- 成功获取

删除Session
当您完成了一个用户的 session 会话数据,您有以下几种选择:
- 移除一个特定的属性: public void removeAttribute(String name) 方法来删除与特定的键相关联的值。
- 删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。
但是刷新后又会生成一个新的Session
因为每次访问浏览器时都会有一个Session对象
- 设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
- 注销用户:如果使用的是支持 servlet 2.4 的服务器,您可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
【体验:】
- Servlet文件
package com.feifan;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class DelSessionAttribute extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name"); // 删除Session内的对应属性
session.invalidate(); // 删除当前Session的ID
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- web.xml映射
<servlet>
<servlet-name>DelSessionAttribute</servlet-name>
<servlet-class>com.feifan.DelSessionAttribute</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DelSessionAttribute</servlet-name>
<url-pattern>/dsa</url-pattern>
</servlet-mapping>
- 先获取当前SessionID

- 删除当前的Session

- 再次获取当前SessionID
进行删除操作后
再次访问你的时候又获得了一个Session对象

浙公网安备 33010602011771号