java 会话共享_java – servlet如何工作?实例化,会话,共享变量和多线程

假设,我有一个拥有大量servlet的Web服务器.对于在这些servlet之间传递的信息,我正在设置会话和实例变量.

现在,如果有2个或更多用户向此服务器发送请求,那么会话变量会发生什么?它们对所有用户都是通用的,或者对于每个用户而言都是不同的.如果它们不同,那么服务器如何区分不同的用户?

还有一个类似的问题,如果有n个用户访问特定的servlet,那么这个servlet只在第一个用户第一次访问它时实例化,或者是否为所有用户分别实例化?换句话说,实例变量会发生什么?

解决方法:

ServletContext中

当servlet容器(如Apache Tomcat)启动时,它将部署并加载其所有Web应用程序.加载Web应用程序时,servlet容器会创建一次ServletContext并将其保留在服务器的内存中.解析web应用程序的web.xml和所有包含的web-fragment.xml文件,并且每个< servlet>,< filter>和< listener>找到(或者分别用@WebServlet,@ WebFilter和@WebListener注释的每个类)实例化一次并保存在服务器的内存中.对于每个实例化的过滤器,使用新的FilterConfig调用其init()方法.

当Servlet具有< servlet>< load-on-startup>或@WebServlet(loadOnStartup)值大于0,然后在启动期间使用新的ServletConfig调用其init()方法.这些servlet按照该值指定的相同顺序进行初始化(1为1,2,为2等) .如果为多个servlet指定了相同的值,则每个servlet的加载顺序与web.xml,web-fragment.xml或@WebServlet类加载中的顺序相同.如果没有“load-on-startup”值,只要HTTP请求第一次访问该servlet,就会调用init()方法.

当servlet容器关闭时,它会卸载所有Web应用程序,调用所有初始化的servlet和过滤器的destroy()方法,并且所有ServletContext,Servlet,Filter和Listener实例都会被删除.最后将调用ServletContextListener#contextDestroyed().

HttpServletRequest和HttpServletResponse

servlet容器连接到Web服务器,该服务器侦听特定端口号上的HTTP请求(端口8080通常在开发期间使用,端口80在生产中使用).当客户端(例如,具有Web浏览器的用户或programmatically using URLConnection)发送HTTP请求时,servlet容器会创建新的HttpServletRequest和HttpServletResponse对象,并将它们传递给链中任何已定义的Filter,最终传递给Servlet实例.

在filters的情况下,调用doFilter()方法.当servlet容器的代码调用chain.doFilter(request,response)时,请求和响应将继续执行下一个过滤器,或者如果没有剩余过滤器则命中servlet.

在servlets的情况下,调用service()方法.默认情况下,此方法根据request.getMethod()确定要调用哪个doXxx()方法.如果servlet中没有确定的方法,则在响应中返回HTTP 405错误.

请求对象提供对HTTP请求的所有信息的访问,例如URL,标题,查询字符串和正文.响应对象提供了以您希望的方式控制和发送HTTP响应的功能,例如,允许您设置标头和正文(通常使用JSP文件中生成的HTML内容).提交并完成HTTP响应后,请求和响应对象都将被回收并可供重用.

HttpSession中

当客户端第一次访问webapp和/或第一次通过request.getSession()获取HttpSession时,servlet容器会创建一个新的HttpSession对象,生成一个长且唯一的ID(可以通过session获取) .getId()),并将其存储在服务器的内存中. servlet容器还在HTTP响应的Set-Cookie标头中设置Cookie,其中JSESSIONID作为其名称,唯一会话ID作为其值.

根据HTTP cookie specification(任何体面的Web浏览器和Web服务器必须遵守的合同),只要cookie有效,客户端(Web浏览器)就需要在Cookie标头中的后续请求中发回此cookie(即唯一ID必须引用未到期的会话,域和路径是正确的).使用浏览器的内置HTTP流量监视器,您可以验证cookie是否有效(在Chrome / Firefox 23 / IE9中按F12,然后选中Net / Network选项卡). servlet容器将检查每个传入HTTP请求的Cookie头是否存在名为JSESSIONID的cookie,并使用其值(会话ID)从服务器的内存中获取关联的HttpSession.

HttpSession保持活动状态,直到它空闲(即未在请求中使用)超过< session-timeout>(web.xml中的设置)中指定的超时值.超时值默认为30分钟.因此,当客户端访问Web应用程序的时间超过指定的时间时,servlet容器会破坏会话.即使指定了cookie,每个后续请求也将无法再访问同一个会话; servlet容器将创建一个新会话.

在客户端,只要浏览器实例正在运行,会话cookie就会保持活动状态.因此,如果客户端关闭浏览器实例(所有选项卡/窗口),则会话在客户端被删除.在新的浏览器实例中,与会话关联的cookie将不存在,因此将不再发送.这会导致创建一个全新的HttpSession,并使用一个全新的会话cookie.

简而言之

>只要Web应用程序存在,ServletContext就会存在.它在所有会话中的所有请求之间共享.

>只要客户端使用相同的浏览器实例与Web应用程序交互,HttpSession就会存在,并且会话在服务器端没有超时.它在同一会话中的所有请求之间共享.

> HttpServletRequest和HttpServletResponse从servlet接收来自客户端的HTTP请求开始,直到完整响应(网页)到达.它不在别处分享.

>只要Web应用程序存在,所有Servlet,过滤器和侦听器实例都会生效.它们在所有会话中的所有请求之间共享.

>只要有问题的对象存在,ServletContext,HttpServletRequest和HttpSession中定义的任何属性都将存在.对象本身表示bean管理框架中的“范围”,例如JSF,CDI,Spring等.这些框架将其作用域bean存储为其最接近匹配范围的属性.

线程安全

也就是说,您主要关心的可能是线程安全.您现在应该知道servlet和过滤器在所有请求之间共享.这是关于Java的好东西,它是多线程的,不同的线程(读取:HTTP请求)可以使用相同的实例.否则,为每个请求重新创建,init()和destroy()它们会非常昂贵.

您还应该意识到,您永远不应将任何请求或会话范围数据分配为servlet或过滤器的实例变量.它将在其他会话中的所有其他请求之间共享.这不是线程安全的!以下示例说明了这一点:

public class ExampleServlet extends HttpServlet {

private Object thisIsNOTThreadSafe;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

Object thisIsThreadSafe;

thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!

thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.

}

}

也可以看看:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267008.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis主从实战

为了提升redis高可用性&#xff0c;除了备份redis dump数据之外&#xff0c;还需要创建redis主从架构&#xff0c;可以利用从将数据库持久化&#xff0c;&#xff08;我们所说的数据持久化将是将数据保存到写磁盘上&#xff0c;保证不会因为断电等因素丢失数据&#xff09; Red…

java 基础面试 英文_[Java面试] 面试java基础总结大全

原标题&#xff1a;[Java面试] 面试java基础总结大全基础知识&#xff1a;1、JVM、JRE和JDK的区别&#xff1a;JVM(Java Virtual Machine):java虚拟机&#xff0c;用于保证java的跨平台的特性。java语言是跨平台&#xff0c;jvm不是跨平台的。JRE(Java Runtime Environment):ja…

在win7环境下使用网络无线共享把电脑变成一台无线路由器

视频教程&#xff1a; http://www.tudou.com/programs/view/PuWxjgYE2Sw/?frrec1&FRLIAN&refid7d145a79fe0ff49f 其中有几点的注意是要把网络设置为WEP、这样的通用性会广泛点、安全性会差点、看实际情况吧、可以先试试用WAP2加密方式、

Ubuntu下安装SSH服务

判断是否安装ssh服务&#xff0c;可以通过如下命令进行&#xff1a;$ ssh localhost ssh: connect to host localhost port 22: Connection refused 如上所示&#xff0c;表示没有还没有安装&#xff0c;可以通过apt安装&#xff0c;命令如下&#xff1a;apt-get install opens…

php字符串怎么传到html_php字符串函数(四):html与字符串之间的转换

* 1.addslashes($str):为了数据库查询语句等的需要在某些字符前加上了反斜线:单引号,双引号,反斜线,建议使用DBMS自带的:mysqli_real_escape_string()* 2.stripslashes($str):功能与addslashes()相反,去掉字符串中的转义反斜线字符* 3.htmlspecialchars($str,FLAG):将特殊字符转…

【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

本系列文章由zhmxy555&#xff08;毛星云&#xff09;编写&#xff0c;转载请注明出处。http://blog.csdn.net/zhmxy555/article/details/7707628作者&#xff1a;毛星云 邮箱&#xff1a; happylifemxy163.com 期待着与志同道合的朋友们相互交流上一节里我们介绍了在迈入…

thinkphp省略php,ThinkPHP的截取字符串函数无法显示省略号的解决方法

对于ThinkPHP的截取字符串函数无法显示省略号的情况&#xff0c;解决方法如下&#xff1a;打开Common/extend.php页面&#xff0c;修改msubstr函数如下&#xff1a;function msubstr($str, $start0, $length, $charset"utf-8", $suffixtrue){if(function_exists(&quo…

Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数)...

Python Day 21 面向对象 (面向对象的三大特性&#xff08;二&#xff09;继承&#xff0c;多态&#xff0c;封装&#xff0c;几个装饰器函数) https://mubu.com/doc/1AqL_M0IbW 继承之钻石继承 多态 封装 几个装饰器函数 classmethod 可以通过类使用被装饰的方法staticmethod …

将Fri May 04 17:25:34 CST 2012形式的日期字符串转换成java.util.Date对象的方法

java.util.Date类的toString()方法默认生成"Fri May 04 17:25:34 CST 2012"形式的字符串&#xff0c;但从这样的字符串生成java.util.Data对象却不那么自然&#xff0c;如下述代码 Date a new Date(); SimpleDateFormat sdf new SimpleDateFormat( "…

php webservice 上传,PHP实现WebService服务

第一步&#xff0c;安装PHP扩展SOAP并开启扩展&#xff0c;是否开启成功以phpinfo为准。第二步&#xff0c;创建服务端文件server.php{public functionhello(){return "Hello World!";}public function sum($num1,$num2){return $num1$num2;}}//创建 SoapServer 对象…

微信小程序小结(3) -- 使用wxParse解析html及多数据循环

wxParse-微信小程序富文本解析组件&#xff1a;https://github.com/icindy/wxParse 支持Html及markdown转wxml可视化 使用 1、copy下载好的文件夹wxParse - wxParse/-wxParse.js(必须存在)-html2json.js(必须存在)-htmlparser.js(必须存在)-showdown.js(必须存在)-wxDiscode.js…

简单实用的分页存储过程,支持多字段排序

CREATE PROCEDURE [dbo].[PublicSplitPage_sp] TableName varchar(8000), --表名 SqlStr varchar(8000)null, --查询语句 Condition varchar(8000), --查询条件 PageIndex int, --页所引&#xff0c;从0开始 PageSize int, --分页大…

php响应超过三十秒会报错么,如何捕捉致命错误:PHP中超过30秒的最大执行时间...

你唯一的select是增加允许的执行时间(将其设置为0使其无限&#xff0c;但不推荐)或产生一个新的线程&#xff0c;并希望最好的。这是不可捕捉的原因是它并没有真正抛出。 没有一行代码实际上触发了这个错误&#xff0c;而是PHP说&#xff1a;“不&#xff0c;不好意思&#xff…

前端代码标准最佳实践:javascript篇

前言 最近一直重构项目的前端代码&#xff0c;也参考了各种前端代码的最佳实践&#xff0c;目的是让前端的HTML,CSS,Javacript代码更符合标准&#xff0c;有更好的性能&#xff0c;更好的可维护性&#xff0c;尝到了重构后的甜头&#xff0c;也萌生了写这个系列博客的念头。前端…

配置springboot在访问404时自定义返回结果以及统一异常处理

在搭建项目框架的时候用的是springboot&#xff0c;想统一处理异常&#xff0c;但是发现404的错误总是捕捉不到&#xff0c;总是返回的是springBoot自带的错误结果信息。 如下是springBoot自带的错误结果信息&#xff1a; 1 { 2 "timestamp": 1492063521109, 3 &…

nginx配置php 9000,Nginx支持php配置

Nginx本身是不支持对外部程序的直接调用或者解析&#xff0c;所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux 下是socket&#xff0c;(这个socket可以是文件socket&#xff0c;也可以是ip socket)。为了调用CGI程序&#xff0c;还需要一个FastCGI的wra…

用例写到抽筋

这几天是第一次写web类的测试用例&#xff0c;不得不说&#xff0c;写web类的测试用例真是会写死人&#xff0c;每一项都要至少写一个测试用例&#xff0c;就算以一项一个用例来算&#xff0c;一个非常非常简单的网站都要写上上百个测试用例。比如说今天写的测试用例中&#xf…

ansible 判断和循环

标准循环 模式一 - name: add several usersuser: name{{ item }} statepresent groupswheelwith_items:- testuser1- testuser2 orwith_items: "{{ somelist }}" 模式2. 字典循环- name: add several usersuser: name{{ item.name }} statepresent groups{{ item.g…

Windows XP中快速识别真假SVCHOST.EXE

SVCHOST.EXE是基于NT核心技术的操作系统非常重要的进程&#xff0c;它提供许多系统服务&#xff0c;比如远程过程调用系统服务 (RPCSS)、动态主机配置协议&#xff08;DPCH) 服务等与网络相关的服务。现在广大计算机用户普遍使用的Windows XP、Windows 2003等操作系统都涉及该进…

php require 500,thinkphp5出现500错误怎么办

thinkphp5出现500错误&#xff0c;如下图所示&#xff1a;require(): open_basedir restriction in effect. File(/home/wwwroot/pic/thinkphp/start.php) is not within the allowed解决方法&#xff1a;1、我是lnmp1.4 php5.6&#xff0c;php.ini里面的open_basedir 是注释掉…