10. Servlet Session 处理

本文介绍了ServletSession处理HTTP无状态协议的方式,探讨了三种维持Web客户端和服务器之间会话的方法:Cookies、隐藏表单字段和URL重写。文章还详细解释了HttpSession接口的功能及其主要API,包括如何获取和管理会话数据。

Servlet Session 处理


  • HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录;
  • 一般有以下3种方式来维持 Web 客户端和 Web 服务器之间的 session 会话
① Cookies
一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别,但是很多浏览器不支持 cookie,因此不建议使用这种方式来维持 session 会话。
② 隐藏的表单字段
一个 Web 服务器可以发送一个隐藏的 HTML 表单字段,以及一个唯一的 session 会话 ID,如下所示:
<input type="hidden" name="sessionid" value="12345">
该条目意味着,当表单被提交时,指定的名称和值会被自动包含在 GET 或 POST 数据中。每次当 Web 浏览器发送回请求时,session_id 值可以用于保持不同的 Web 浏览器的跟踪。
这可能是一种保持 session 会话跟踪的有效方式,但是点击常规的超文本链接(<A href...>)不会导致表单提交,因此隐藏的表单字段也不支持常规的 session 会话跟踪。
③ URL 重写
可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。
例如,http://w3cschool.cc/file.htm;sessionid=12345,session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。
URL 重写是一种更好的维持 session 会话的方式,它在浏览器不支持 cookie 时能够很好地工作,但是它的缺点是会动态生成每个 URL 来为页面分配一个 session 会话 ID,即使是在很简单的静态 HTML 页面中也会如此。

除了以上3种方式以外不同后端语言提供了不同的具体实现来更加有效地维持 Session 跟踪,PHP提供了与 session 操作相关的一系列函数,而 Servlet 提供了 javax.servlet.http.HttpSesssion 接口实现 Session 的跟踪;


HttpSession 对象处理 Session


  • HttpSession 接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式;
  • Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求;

可以通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象:
 
 HttpSession session = request.getSession();
HttpSession中主要的API如下:
String getId()
返回一个包含分配给该 session 会话的唯一标识符的字符串。
Object getAttribute(String name)
返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null
Enumeration getAttributeNames()
返回 String 对象的Enumeration,String 对象包含所有绑定到该 session 会话的对象的名称。
void removeAttribute(String name)
从该 session 会话移除指定名称的对象。
void setAttribute(String name, Object value)
使用指定的名称绑定一个对象到该 session 会话
long getCreationTime()
返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
long getLastAccessedTime()
返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
int getMaxInactiveInterval()
返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位
void setMaxInactiveInterval(int interval)
在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。
void invalidate()
指示该 session 会话无效,并解除绑定到它上面的任何对象。
boolean isNew()
如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。

以下是一个关于Session追踪的示例:
 利用Session实现同一个会话中对访问次数进行计数的功能
 
public class Demo extends HttpServlet{
    public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IoException{
        
        //创建session(参数true表示在页面不存在Session时创建该Session)
        HttpSession session = request.getSession(true);
        
        //获取一些session信息
        String sessionId = session.getId();
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String createTime = format1.format(new Date(session.getCreationTime()));
        String lastAccessTime = format1.format(new Date(session.getLastAccessTime()));
        
        //计算vistCount,并重新写入到session中
        int vistCount = 0;
        if(!session.isNew())  //当session不是首次产生时,开始计数
            vistCount = (Integer)session.getAttribute("vistCount") + 1;
        session.setAttribute("vistCount",vistCount);
        
        //返回响应正文
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE html><html><body>");
        out.println("<p>session id:"+sessionId+"</p>");
        out.println("<p>create time:"+createTime+"</p>");
        out.println("<p>last access time:"+lastAccessTime+"</p>");
        out.println("<p>vist count"+vistCount+"</p>");
        out.println("</body></html>");
    }
}








<think>首先,用户的问题是:“我想了解或配置server.servlet.session.cookie.same-site的设置请问如何在SpringBoot中配置server.servlet.session.cookie.same-site属性”根据系统级指令,我需要:1.使用$...$格式处理行内数学表达式(但在这个问题中,似乎没有数学表达式,所以可能不需要)。2.独立公式使用$$...$$格式(同样,可能不适用)。3.LaTeX语法正确(确保任何LaTeX正确)。4.使用中文回答。5.生成相关问题。6.回答中引用的段落末尾自然地添加引用标识,例如[^1]。用户可见层指令:回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。参考提供的引用:-引用[1]:提到server.servlet.session.cookie.same-site属性用于更改会话cookie的SameSite属性,支持Tomcat、Jetty和Undertow服务器。-引用[2]:是关于安全配置的代码示例,但似乎不直接相关。-引用[3]:提到在JavaWeb应用中设置Cookie时,javax.servlet.http.Cookie没有设置SameSite的方法。-引用[4]:是关于设置Session属性的代码。-引用[5]:是关于循环引用的错误。用户的问题集中在SpringBoot中配置server.servlet.session.cookie.same-site属性。关键信息来自引用[1]:"如果要更改会话cookie的SameSite属性,可以使用server.servlet.session.cookie.same-site属性。自动配置的Tomcat、Jetty和Undertow服务器支持此属性。"所以,我需要解释如何在SpringBoot中配置这个属性。步骤:1.**解释属性**:SameSite属性控制cookie是否在跨站点请求中发送,有助于防止CSRF攻击。值可以是Strict、Lax、None。2.**配置方法**:在SpringBoot中,可以通过application.properties或application.yml文件设置。-对于application.properties:server.servlet.session.cookie.same-site=Lax(或Strict,None)-对于application.yml:```server:servlet:session:cookie:same-site:Lax```3.**注意事项**:-确保服务器支持(如引用[1]所述)。-如果使用None,cookie必须标记为Secure(即通过HTTPS发送)。-在旧版本Servlet中,可能不支持,但SpringBoot可能处理了兼容性(引用[3]提到Servlet库可能没有直接方法)。4.**代码示例**:提供一个简单的例子。5.**生成相关问题**:在回答末尾添加相关问题。结构回答:-开头简要解释SameSite属性。-逐步指导如何配置。-添加引用标识在相关段落末尾。-最后生成相关问题。确保使用中文。</think>### 如何在Spring Boot中配置server.servlet.session.cookie.same-site属性 在Spring Boot中,`server.servlet.session.cookie.same-site`属性用于控制会话cookie的SameSite属性,这有助于增强应用的安全性,防止跨站请求伪造(CSRF)攻击。SameSite属性定义了cookie是否在跨站点请求中发送,其值通常包括`Strict`、`Lax`或`None`(其中`None`要求cookie必须通过HTTPS传输)。Spring Boot自动支持Tomcat、Jetty和Undertow等嵌入式服务器,通过该属性简化配置[^1]。以下是逐步配置指南: #### 步骤1: 理解属性值 - **Strict**: cookie仅在相同站点请求中发送,适用于高安全场景。 - **Lax**: cookie在导航到目标站点的安全请求中发送(如GET请求),是默认推荐值。 - **None**: cookie在所有跨站点请求中发送,但必须同时设置`Secure`属性(即仅通过HTTPS生效)。 如果您未设置该属性,Spring Boot默认使用服务器实现(Tomcat等)的默认值,通常为`Lax`。 #### 步骤2: 在配置文件中设置属性 在Spring Boot中,您可以直接在`application.properties`或`application.yml`文件中配置该属性。以下以常见格式说明: - **使用application.properties文件**: 打开`src/main/resources/application.properties`,添加一行: ```properties server.servlet.session.cookie.same-site=Lax # 可选值:Strict、Lax、None ``` 如果您需要设置`None`值(用于跨站点场景),必须同时启用`Secure`属性: ```properties server.servlet.session.cookie.secure=true # 强制HTTPS server.servlet.session.cookie.same-site=None ``` - **使用application.yml文件**: 打开`src/main/resources/application.yml`,添加以下YAML结构: ```yaml server: servlet: session: cookie: same-site: Lax # 可选值:Strict、Lax、None secure: true # 当same-site=None时必需 ``` #### 步骤3: 验证配置 - 启动应用后,检查浏览器中的会话cookie(例如通过开发者工具的Application > Cookies部分)。SameSite属性应显示为设置的值。 - 如果使用`None`值,请确保应用部署在HTTPS环境下,否则浏览器可能忽略cookie。 #### 注意事项 - **兼容性问题**: 在旧版本Servlet(如Java EE 8之前)中,`javax.servlet.http.Cookie`类可能不直接支持SameSite属性[^3]。但Spring Boot通过自动配置处理了这一问题,您无需手动修改Cookie对象。 - **服务器支持**: 该属性仅适用于Spring Boot的嵌入式服务器(Tomcat、Jetty、Undertow)。如果您使用外部服务器(如独立Tomcat),需在服务器配置中单独设置。 - **Spring Session集成**: 如果您使用Spring Session管理会话,该属性也会自动应用到`SessionRepository` bean[^1]。 - **错误处理**: 如果配置后出现循环引用或bean冲突错误,检查依赖注入是否合理,或临时设置`spring.main.allow-circular-references=true`作为最后手段[^5]。 通过以上步骤,您可以轻松配置SameSite属性,提升应用安全性。如果您遇到问题,建议查阅Spring Boot官方文档或使用IDE的配置提示功能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值