上一篇文章JavaWeb-Servlet服务连接器(三)_Alphamilk的博客-CSDN博客
目录
1.ServletContext通信
会话技术Cookie与Session
1.Cookie
2.Session
1.ServletContext通信
概念:代表了整个web应用,用于与服务器实现通信
可以通过以下方法获取该对象
方法 | 描述 |
---|---|
request.getServletContext() | 返回与给定请求关联的Servlet上下文对象。 |
this.getServletContext() | 返回当前Servlet的上下文对象。它是通过servlet类自动继承的方法,可以在当前servlet中直接调用。 |
获取的对象可以实现以下功能
获取MIME类型(互联网通信时候用到的文件类型)
方法 | 描述 |
---|---|
request.getServletContext().getMimeType(String file) | 返回给定文件的 MIME 类型。可以通过请求的 Servlet 上下文对象调用,传入文件路径或文件名作为参数。 |
this.getServletContext().getMimeType(String file) | 返回给定文件的 MIME 类型。可以在当前 Servlet 中直接调用,传入文件路径或文件名作为参数。 |
常见的MIME类型
MIME类型 | 描述 |
---|---|
text/plain | 纯文本 |
text/html | HTML文档 |
text/css | CSS样式表 |
application/json | JSON数据 |
application/xml | XML数据 |
application/pdf | Adobe PDF文件 |
application/msword | Microsoft Word文档 |
image/jpeg | JPEG图像 |
image/png | PNG图像 |
案例代码:
package com.company;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/ContextDemo")
public class ServletContextdemo extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 定义文件名
String filename = "javaWeb.jpg";
// 通过request创建对象
ServletContext context = req.getServletContext();
// 通过HttpServlet本身的方法创建ServletContext
ServletContext context1 = this.getServletContext();
// 获取文件名的mimeType类型
String mimeType = context.getMimeType(filename);
System.out.println("FileName:"+filename+" MIMEType:"+mimeType);
}
// 方法统一
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
2. 域对象(实现共享数据)
通过以下方法实现
方法 | 描述 |
---|---|
setAttribute(String name, Object obj) | 将给定名称和对象绑定在当前范围内(如servlet上下文、会话或请求)。 |
getAttribute(String name) | 返回与给定名称关联的对象,如果没有找到则返回null。 |
remove(String name) | 从当前范围中删除具有给定名称的属性,并返回被删除的属性值,如果没有找到则返回null。 |
案例代码:
设置共享变量类
package com.company;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Contextdemo3")
public class Contextdemo3 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
// 创建共享变量
context.setAttribute("msg","HelloWorld");
System.out.println("访问ContextDemo3");
}
// 方法统一
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
获取共享变量类
package com.company;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Contextdemo4")
public class Contextdemo4 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
// 获取共享变量
Object msg =context.getAttribute("msg");
System.out.println("访问ContextDemo4");
// 如果消息可以进行转型字符串则转型为字符串
if (msg instanceof String){
System.out.println((String) msg);
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
3.获取文件的真实路径
方法名 | 描述 |
---|---|
getRealPath(String path) | 获取指定路径下资源在服务器文件系统中的真实路径 |
案例代码:
就以刚才javaWeb.jpg举例,找到其在服务器中的位置
package com.company;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/ContextDemo2")
public class ContextDemo2 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用HttpServlet创建对象
ServletContext context = this.getServletContext();
// 通过相对于部署的 Web 应用程序的根目录的路径来获取真实路径
String realpath = context.getRealPath("/src/javaWeb.jpg");
System.out.println("在服务器中存放的路径是:"+realpath);
}
// 方法统一
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
对比可以发现确实是在该位置
会话技术Cookie与Session
1.Cookie
cookie是客户端的会话数据,并且将数据保存到客户端浏览器,可以保存一些并不重要的信息,比如购物车网站,当选好购物的商品的时候如果关闭了浏览器,如果没有Cookie技术则会丢失购买记录,需要重新进行购物。
Cookie的创建、设置、获取
方法名 | 描述 |
---|---|
Cookie(String name, String value) | 创建一个新的 Cookie 对象,使用给定的名称和值 |
response.addCookie(Cookie cookie) | 将指定的 Cookie 添加到响应中 |
response.getCookies() | 获取响应中包含的所有 Cookie,并将其以数组形式返回 |
Cookie生命周期
每一个Cookie都有一定的生命周期,当超过有效时间时候就会失效,默认情况下,Cookie的创建生命周期直到客户端的浏览器关闭就失效,而如果不存在失效的情况下太多的Cookie被浏览器保存下来会造成大量的资源占用。可以通过以下方法控制生命周期
方法名 | 描述 |
---|---|
setMaxAge(int seconds) | 设置 Cookie 的最大存活时间(以秒为单位)。 |
- 当 seconds 为 0 时,表示该 Cookie 将立即过期并从客户端删除。 | |
- 当 seconds 为负数时,表示该 Cookie 是一个会话 Cookie,只在用户会话期间有效,关闭浏览器后将被删除。 | |
- 当 seconds 大于0时,表示该 Cookie 将在指定的秒数后过期。 |
创建Cookie的案例代码:
设置Cookie类(案例情景:在成功登陆一些网站时候,就授予Cookie用以可以记录用户的操作)
package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/CookieDemo1")
public class CookieDemo1 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建一个Cookie表示购物袋中有一辆兰博基尼,并且传入多个cookie
Cookie cookie = new Cookie("shoppingMap","Lamborghini");
Cookie cookie1 = new Cookie("login-id","1234");
// 第一个保留七天数据,第二个默认处理
cookie.setMaxAge(60*60*7);
resp.addCookie(cookie);
resp.addCookie(cookie1);
}
// 方法统一处理
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
访问Cookie类
package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/CookieDemo2")
public class CookieDemo2 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookies[] = req.getCookies();
// 输出所有的Cookie数据
for (Cookie c:cookies) {
String name = c.getName();
String value = c.getValue();
System.out.println("CookieName:"+name+" CookieValue:"+value);
}
}
// 统一方法处理
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
查看发送的数据包:
Cookie的特点与作用
特点:
- cookie的内容存储在客户端的浏览器上
- 浏览器对单个cookie的大小有限制,并且对同一个域名的cookie的数量也有限制
作用:
- cookie常用于存储少量不太敏感的数据
- 在未登陆的情况下能够实现服务器对用户的身份识别
注意:cookie不应该用于记录用户的登陆的唯一标识,因为如果有人通过伪造cookie的方式(比如sql注入,或者csrf外部绕过)从而登陆到相关的网站,并对用户的信息进行非法修改,造成损失
2.Session
Seesion也是一门服务器的会话技术,但是相比与Cookie,其数据保存在服务器中。一般用来识别与跟踪用户的状态信息。
Session的创建、使用
方法 | 描述 |
---|---|
HttpSession session = request.getSession() | 创建或获取当前请求的 HttpSession 对象,如果不存在则会创建一个新的。 |
session.getAttribute(String name) | 获取指定名称的属性值,返回一个 Object 类型的值。 |
session.setAttribute(String name, Object value) | 设置指定名称的属性值,将 Object 类型的值存储到 Session 中。 |
session.removeAttribute(String name) | 移除指定名称的属性值。 |
案例代码:创建session对象并赋值
创建类
package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/SessionDemo1")
public class SessionDemo1 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建Session
HttpSession session = req.getSession();
session.setAttribute("用户name","AlphaMilk");
System.out.println("设置session成功");
}
// 方法统一
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
获取session类:
package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/SessionDemo2")
public class SessionDemo2 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 告诉浏览器服务器的编码方式是utf-8
resp.setHeader("content-type","text/html;charset=utf-8");
// 获取请求头的session对象
HttpSession session = req.getSession();
// 创建输出流,将session内容输出到浏览器中
PrintWriter writer = resp.getWriter();
writer.write("<h1>欢迎用户"+session.getAttribute("用户id")+"</h1>");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
问题引出:如果客户端浏览器不小心关闭,再次开启浏览器获取到的session将是不同的对象。那么该如何解决这个问题呢?
Session 的实现通常依赖于 Cookie。每次创建 Session 时,会生成一个对应的 Cookie,其中包含了一个称为 JSESSIONID 的标识符,用于唯一标识该 Session 对象。
在客户端发起请求时,浏览器会自动将该 Cookie 携带到服务器端,服务器通过解析 Cookie 中的 JSESSIONID,就能够找到对应的 Session 对象,从而实现状态的保持和用户身份的识别。
实现session持久化
解决方法本质就是创建一个一模一样的cookie中JSESSIONID和值
案例代码:
package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/SessionDemo3")
public class SessionDemo3 extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建session对象
HttpSession session = req.getSession();
// 创建对应的cookie对象
Cookie cookie = new Cookie("JSESSIONID",session.getId());
// 设置生命周期
cookie.setMaxAge(60*60);
resp.addCookie(cookie);
// 获取session对象的id
System.out.println(req.getSession().getId());
}
// 实现方法统一
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
第一次获取然后关闭浏览器重新获取id
Session的销毁
- 服务器关闭
- session调用invalidate()
- session修改默认失效时间
session的默认失效时间是30分钟如果想要修改需要在项目的总web.xml配置中设置
<session-config>
<session-timeout>30</session-timeout>
</session-config>