Servlet入门
奉劝那些好高骛远的人,各种框架搞不懂?学好servlet就够了。
文章目录
- Servlet入门
- 前言
- 一、Web应用开发基础
- 二、HTTP
- 三、 Java Web应用程序的规范目录结构
- 四、 Tomcat
- 五、Servlet
- 六、Session会话
前言
本文将带着初学者从最底层的servlet学起,探索CS交互的乐趣。
手机app暂不支持目录跳转
一、Web应用开发基础
1. 应用程序分类
桌面应用程序(Desktop Application)
一般是指采用Client/Server即客户机/服务器结构(简称CS结构)的应用程序。
服务器端程序主要等待响应客户程序发来的请求。客户端需要安装专用的客户端程序。
典型应用:QQ程序。
- 优点:客户端响应速度快。
- 缺点:高昂的维护、升级成本且投资大兼容性低
Web应用程序(Web Application)
一般是指采用Browser/Server即浏览器和服务器结构(简称BS结构)的应用程序。
客户机上只要安装一个浏览器,服务器端程序等待响应客户端发来的请求。
浏览器通过网络跟服务器端程序进行数据交互。
典型应用:门户网站、webQQ
- 优点:客户端零维护,维护和升级方式简单成本降低
Web应用程序的两端
- Web服务器:接收客户请求,进行处理,然后向客户返回结果(响应)。
- Web客户:允许用户请求服务器上的某个资源,并且向用户显示请求的结果。
二、HTTP
1. URL
URL(Uniform Resource Locators):统一资源定位符
Web上的每个资源都有唯一的地址,采用的就是URL格式
2. HTTP协议
HyperText Transfer Protocol:超文本传输协议。用于定义浏览器与web服务器之间交换数据的过程以及数据格式。
- 它是以TCP/IP为基础的高层协议。
- HTTP是以明文方式传输数据的无状态协议。
当用户在浏览器地址栏输入某个URL地址,或单击网页上一个超链接,或提交网页上的Form表单时,浏览器将生成HTTP请求消息发送给服务器。
服务器收到请求消息后进行处理,并生成HTTP响应消息回送给浏览器。
3. HTTP/1.1
现在广泛使用的版本HTTP/1.1。相对于HTTP/1.0来说,最大的特点就是支持持续连接(即一次TCP连接上可以包含多次请求和响应)。
一个包含许多图像的网页文件的多个请求和响应可以在一个连接中传输,但每个单独的网页文件的请求和响应仍然需要使用各自的连接。
HTTP/1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求。
4. HTTP消息
- 请求消息:客户端(浏览器)向服务器发送的HTTP请求超文本。
请求消息中的关键要素是:HTTP请求方式,要访问的资源(URL),表单参数数据。 - 响应消息:服务器向客户端返回的HTTP响应超文本。
响应消息中的关键要素是:状态码、响应内容的类型(也叫MIME类型)、具体的响应内容(HTML、图像等数据)。
HTTP请求消息格式
一个完整的请求消息包括一个请求行、若干消息头以及消息体。消息头和消息体之间要用空行隔开。
- 请求行指定请求方式,资源路径及使用的协议版本
- 消息头用来描述HTTP消息本身的一些属性
- 消息体是请求消息的正文
HTTP请求常用的方式是GET和POST
注:具体可通过Chrome浏览器的开发者工具查看
GET请求消息格式
GET请求消息
在浏览器地址栏输入某个URL地址或单击网页上某一个超链接
提交网页上method属性未设置或设置为"GET"的Form表单
GET /javaweb-demo/login?lname=admin&pwd=1234HTTP/1.1
Accept:image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Referer: http://192.168.1.100:8080/javaweb-demo/index.html
Accept-Language: en-us,zh-cn;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2;
.NET4.0C; .NET4.0E; .NET CLR 2.0.50727)
Host: 192.168.1.100:8080
Connection: Keep-Alive
特点:
- GET方式会把要传送的请求参数数据追加到URL后面,再提交到服务器
http://localhost:8080/javaweb-demo/login.do?lname=admin&pwd=admin - 会在浏览器地址栏中显示出来,所发送的数据会完全暴露。
- GET方式传送的数据量有限制。
一般来说,浏览器地址栏的字符长度限制为2k字符。
POST请求消息格式
POST请求消息
提交网页上method属性设置为"POST"的Form表单
POST /javaweb-demo/login.doHTTP/1.1
Accept:image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Referer: http://192.168.1.100:8080/javaweb-demo/index.html
Accept-Language: en-us,zh-cn;q=0.5
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2;
.NET4.0C; .NET4.0E; .NET CLR 2.0.50727)
Host: 192.168.1.100:8080
Content-Length: 21
Connection: Keep-Alive
Cache-Control: no-cache
lname=admin&pwd=admin
特点
- 发送的请求参数数据是作为HTTP消息的消息体来发送的。不会作为URL地址的参数传递。
- 理论上,POST传送的数据量没有限制
HTTP响应消息格式
完整的响应消息包括一个状态行、若干消息头以及消息体。
- 状态行告诉浏览器使用了什么协议,请求是否成功
- 消息头用来描述HTTP消息本身的一些属性
- 消息体包含了要让浏览器显示的具体内容(例如:HTML)
HTTP/1.1 200 OK
Server:Apache-Coyote/1.1
Content-Type:text/html;charset=UTF-8
Transfer-Encoding:chunked
Date:Fri, 19 Sep 2008 07:36:11 GMT
<HTML>
<HEAD><TITLE>用户登录验证</TITLE></HEAD>
<BODY>
处理GET请求<br>
欢迎会员:admin登录
</BODY>
</HTML>
响应状态码
状态码 | 英文描述 | 中文描述 |
---|---|---|
200 | OK | 正常 |
302 | Found | 重定向到Location域指出的URI |
304 | Not Modified | 未修改,服务器上对应文档未修改,客户机本地缓存的文档是最新的,客户机应该继续使用它 |
400 | Bad Request | 无效请求,客户机的请求有不正确的语法格式 |
403 | Forbidden | 禁止,服务器理解客户端的请求,但拒绝处理它 |
404 | Not Fuound | 未找到,服务器不存在客户机所请求的资源 |
405 | Method Not Allowed | 不允许此请求方法,请求行中的请求方式对指定的资源不适用 |
500 | Internal Server Error | 服务器内部错误,服务器端的程序发生错误而不能完成请求 |
503 | Service Unavailable | 服务不可用,由于当前负载过大 |
MIME类型
ultipurpose Internet Mail Extensions:多用途互联网邮件扩展。是描述消息内容类型的因特网标准。它包含文本、图像、音频、视频以及其他应用程序专用的数据
常用MIME类型 | 描述 |
---|---|
text/html | HTML文本 |
image/gif(image/jpeg)(image/png) | 图像 |
application/msword | Word文件 |
application/msexcel | Excel文件 |
application/json | JSON文件 |
application/octet-stream | 二进制数据 |
常用:
text/html;charset=UTF-8
application/json;charset=UTF-8
三、 Java Web应用程序的规范目录结构
1. Web应用程序目录结构
2. Java Web应用程序开发过程
步骤:
- 设计目录结构
- 编写Web应用程序代码
- 编写部署描述符: web.xml
- 编译代码
- 将Web应用程序打包(xxx.war)
- 部署Web应用程序 -> Web容器
- 执行Web应用程序
四、 Tomcat
- 常用开源的Servlet/JSP容器:Apache组织Jakarta项目中的Tomcat、CAUCHO公司的Resin、Webtide公司的Jetty
- Tomcat是Sun公司推荐的运行Servlet和JSP的容器(引擎),其源代码完全公开。
- 也提供一些Web服务器的功能。如:数据连接池、SSL、Proxy等。
- Tomcat不同版本对Servlet和JSP的版本支持不同
1. Tomcat配置
- 安装:使用解压缩版本
需要在环境变量中指定JAVA_HOME变量:值为JDK的安装目录。 - 目录结构
CATALINA_HOME
|-- bin/ 二进制可执行文件和脚本:startup.bat、shutdown.bat
|-- conf 配置文件目录
|-- lib/ 存放Web应用程序的共享类库的目录
|-- logs/ 日志目录
|-- temp/ 存放临时产生的文件
|-- webapps/ 存放Web应用程序的目录
|-- work/ Tomcat的工作目录(存放JSP产生的class文件)
2. JavaWeb应用的部署
- Web应用可以直接放在Tomcat的webapps目录下面—开发阶段
- 也可以通过配置虚拟目录方式—产品阶段
修改conf/server.xml文件,在里面添加如下代码
<Contextpath="/应用上下文名"
docBase="实际项目目录位置"
debug="0"
reloadable="true"/>
五、Servlet
Servlet是一个用Java编写的程序,此程序在服务器上运行用来处理Web客户端请求,并作出响应
优点:执行效率高。Servlet默认是以多线程模式执行的。拥有跨平台执行能力
1. 第一个Servlet应用
定义Servlet类
importjava.io.IOException;
importjava.io.PrintWriter;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/*自定义的Servlet 是需要继承自HTTPServlet*/
public class MyServlet extends HttpServlet {
/*
在Servlet中 常用两个方法 doGet 用来处理Get请求过来的内容 一个是doPost用来处理Post请求
doXxx(HttpServletRequest req , HttpServletResponse resp)
两个参数 用来对应 req对应请求对象 resp用来对应响应对象 主要用来和客户端(浏览器)进行交互
req 和 resp 不需要人为管理 Web容器(Tomcat)来帮我们进行创建
Servlet3.x之前 是需要在web.xml中进行配置映射的
Servlet3.x 之后需要在类中使用注解进行映射配置
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("请求抵达了MyServlet---Get方式!!!!!");
//登录验证
//接收用户发送过来的参数所有的数据在网络传输中都会采用默认的字符集 ISO-8859-1
// 必须在接收数据前指定当前数据的接收字符集为UTF-8
req.setCharacterEncoding("UTF-8");
String user=req.getParameter("user");
String pwd=req.getParameter("pwd");
System.out.println("用户名:"+user+",密码:"+pwd);
resp.setContentType("text/html;charset=utf-8");//设置响应类型(MIME) 顺便设置字符编码格式为UTF-8
PrintWriter out=resp.getWriter();
out.println("<!DOCTYPE HTML>");
out.println("<html>");
out.println("<head>");
out.println("<title>登录</title>");
out.println("<meta charset='utf-8'/>");
out.println("</head>");
out.println("<body>");
if(null!=user&&null!=pwd&&!user.isEmpty() &&!pwd.isEmpty()){
if("admin".equals(user) &&"123".equals(pwd)){
out.println("恭喜"+user+" <span style='color:red'>登录成功!</span>");
}else{
out.println("用户名或密码错误!!");
out.println("<a href=\"index.html\">返回登录页</a>");
}
}
out.println("</body>");
out.println("</html>");
//经过逻辑判定后给客户端进行响应
}
@Override
protected void doPost(HttpServletRequestreq, HttpServletResponseresp)
throws ServletException, IOException {
System.out.println("请求抵达MyServlet---Post");
doGet(req,resp);
}
}
配置Servlet映射路径
在web.xml 中进行配置
<servlet>
<!-- 给当前的Servlet起一个名称认为是一个key值对应一个value值
key值一般来说和Servlet的类名保持一致
-->
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.liqk.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 给某个Servlet进行一个路径映射
key 和某个被容器管理的Servlet中key值保持一致
value
-->
<servlet-name>MyServlet</servlet-name>
<!--配置Mapping时需要加/ 表示项目根目录当前项目web目录 -->
<url-pattern>/first</url-pattern>
</servlet-mapping>
部署应用
Servlet没有main()方法。它受控于另一个Java应用,这个Java应用称为Servlet容器(引擎)。Tomcat就是这样一个容器。
把Servlet所在的web程序部署到Tomcat容器中,启动Tomcat容器之后,就可以访问这个Servlet了
访问Servlet
当客户端提交的请求URL符合web.xml中对应的URL匹配模式时,容器将调用对应的Servlet来处理该请求。
请求URL格式为:http://服务器地址:端口号/Web应用上下文路径/资源名
如:http://localhost:8080/servlet-01-core/first
示例
用户登录验证
<!doctype html>
<html>
<head>
<metacharset="UTF-8"/>
<title>login.html</title>
</head>
<body>
<h3>登录验证</h3>
<form action="login" method="post">
<table border="1" width="600">
<tr><td>用户名</td><td>
<input type="text" name="user"/></td></tr>
<tr><td>密码</td><td>
<input type="password" name="pwd"/></td></tr>
<tr><td colspan="2"><input type="submit" value="提交"/></td></tr>
</table>
</form>
</body>
</html>
2. web容器调用Servlet处理请求过程
Servlet 请求处理过程
容器接收到一个指向某个servlet的请求时
- 容器实例化Servlet(单例)
- 容器会启动一个线程
容器给servlet提供(创建)请求对象和响应对象 - 容器调用servlet的请求处理方法
- 容器将结果响应给客户端
- 容器会结束这个线程
3. Servlet生命周期
- 实例化和初始化:
- Web容器对Servlet进行实例化:Web容器回调它的无参构造方法
- 实例化完成之后,马上进行初始化工作。Web容器回调init()方法
- 服务:请求路径匹配上Servlet的URL映射时。
- Web容器启动一个线程,在线程中回调service方法—service方法中根据请求方式来调用不同的处理方法(doGet()或doPost())
- doGet()和doPost()方法要注意线程安全问题
- 销毁:Web容器在卸载Web应用程序前
Web容器回调destroy()方法,一般用于清理一些资源
4. Servlet API
Java EE(J2EE) API 规范由Sun公司提供,容器厂商提供具体实现。
Servlet和JSP属于JavaEE中的一种技术。
Tomcat作为Servlet容器,提供了Servlet/JSP API的具体实现。
Java EE API文档下载
HttpServlet的主要回调方法
- public void init()
- public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException,ServletException
- public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException,ServletException
- public void destroy()
HttpServletRequest 常用方法
方法 | 描述 |
---|---|
void setCharacterEncoding(String charsetName) | 设置请求消息体的编码字符集。注:对get请求传递的数据无效。web容器默认采用”ISO-8859-1”解析POST数据。必须在调用getParameter()之类方法之前设置才有效 |
String getParameter(String name) | 获取指定名称的请求参数的字符串值 |
String[] getParameterValues(String name) | 返回指定名称的请求参数的所有字符串值数组。适用于复选框、多选列表。 |
String getContextPath() | 获取请求URL所属于的Web应用程序的路径。表示相对于整个Web站点的根目录。这个路径以/开头,结尾不包含/。 |
void setCharacterEncoding(String charsetName) | 设置请求消息体的编码字符集。注:对get请求传递的数据无效。web容器默认采用”ISO-8859-1”解析POST数据。必须在调用getParameter()之类方法之前设置才有效 |
String getRemoteAddr() | 获取发出请求的客户机的IP地址。注:服务器Win7以上系统,获取的是IPV6地址问题 |
String getHeader(String name) | 获取指定名称的消息头字段的字符串值 |
RequestDispatcher getRequestDispatcher(String path) | 获取请求分派器 |
void setAttribute(String name,Object obj) | 操作请求域属性中的属性 |
Object getAttribute(String name) | |
void removeAttribute(String name) | |
HttpSession getSession() | 获取与当前请求关联的会话对象。 |
HttpSession getSession(boolean create) | |
Cookie[] getCookies() | 获取当前请求所携带的所有Cookie对象数组 |
HTTPServletResponse 常用方法
方法 | 描述 |
---|---|
void setContentType(String type) | 设置响应内容类型。如text/html;charset=UTF-8、application/json;charset=UTF-8 容器默认采用”ISO-8859-1”编码响应数据。必须在调用getWriter()之类方法之前设置才有效 |
PrintWriter getWriter() | 获得字符输出流对象。用于向客户端输出文本数据 |
ServletOutputStream getOutputStream() | 获得字节输出流对象。用于向客户端输出字节数据 |
void addHeader(Stringname, String value) | 向响应消息中添加头信息向响应消息中设置头信息 |
void setHeader(String name,String value) | |
void sendRedirect(String location) | 重定向到指定的URL |
void addCookie(Cookie cookie) | 向客户端发送Cookie信息 |
void encodeURL(String url) | 对URL进行编码。如果客户不支持Cookie,就会给指定的URL增加额外的会话ID信息 |
示例: 网页版计算机
index.jsp
<!doctype html>
<html>
<head>
<metacharset="UTF-8"/>
<title>计算器</title>
</head>
<body>
<h3>计算器</h3>
<form action="calculate" method="post">
<table border="1" width="600px">
<tr><td>第一个数</td><td><input type="text" name="num1"/></td></tr>
<tr><td>运算符</td><td><select name="opt">
<option value="+"> + </option>
<option value="-"> - </option>
<option value="*"> * </option>
<option value="/"> / </option>
</select></td></tr>
<tr><td>第二个数</td><td><input type="text" name="num2"/></td></tr>
<tr><td colspan="2"><input type="submit" value="提交"/></td></tr>
</table>
</form>
</body>
</html>
result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Result</title>
</head>
<body>
${result}
</body>
</html>
CalculatorResultServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/calculate")
public class CalculatorResultServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String num1 = req.getParameter("num1");
String opt = req.getParameter("opt");
String num2 = req.getParameter("num2");
float a= Float.parseFloat(num1);
float b= Float.parseFloat(num2);
float rs = 0;
PrintWriter out = resp.getWriter();
if(null!=opt||!"".equals(opt)){
if ("+".equals(opt)){
rs=a+b;
req.setAttribute("result",rs);
}else if ("-".equals(opt)){
rs=a-b;
req.setAttribute("result",rs);
}else if ("*".equals(opt)){
rs=a*b;
req.setAttribute("result",rs);
}else if ("/".equals(opt)){
rs=a/b;
}
}else {
out.println("程序出错!!!");
}
req.getRequestDispatcher("result.jsp").forward(req,resp);
}
}
文档结构
5. Servlet访问规则
- URL匹配模式
- 确切路径匹配:以"/"开始,后面跟一个具体的路径名称,也可以包含子路径。
"/"代表该Web应用的根路径。
在该匹配模式下,客户端只能通过这一唯一的路径来访问该Servlet实例。
如:/hello、/mng/index、/user/logout.do。 - 模糊路径匹配:以"/“开始,以”/"结束,中间可以包含子路径
客户端可以通过一组相关的路径来访问该Servlet的实例。
如:/、/basic/、/user/mng/ 。 - 扩展名匹配:以“.”开始,以任意其它的字符结束。
客户端可以通过一组相关的路径来访问该Servlet的实例
如:.do、.action、.ctrl等都属于扩展名的匹配。 - 缺省的Servlet:配置成“/”的Servlet为该应用的缺省Servlet,Web服务器会将所有无法识别的客户端请求交给缺省的Servlet来处理。
Web容器匹配Servlet的顺序规则
具体顺序规定如下:
- 寻找确切路径匹配的Servlet。
- 如果没有确切的路径匹配,按照模糊路径匹配,如果有多个路径存在,取固定部分路径最长的Servlet。
- 寻找扩展名匹配。
- 如果上述规则都无法匹配到Servlet,系统会将请求交给缺省的Servlet处理。
报告404错误信息给调用者
6. Web应用启动时创建Servlet实例
在web.xml注册Servlet时,可通过标签来通知Web容器在部署该Web应用时就创建该Servlet的实例:
<servlet>
<servlet-name>timeServlet</servlet-name>
<servlet-class>com.liqk.web.TimeServlet</servlet-class>
<load-on-startup>10</load-on-startup>
</servlet>
- 指定的整数值:
- 正数或零:该Servlet必须在应用启动时装载,容器必须保证数值小的Servlet先装载,如果有多个Servlet的取值相同,由容器决定它们的装载顺序。
- 负数或没有指定:由容器来决定装载的时机,通常为第一个请求到来时。
7. Servlet交互
在Servlet程序中,有时需要在一个Servlet中调用另一个资源来对浏览器的请求进行响应,这可以通过两种方式来实现:
- 调用HttpServletResponse.sendRedirect 方法实现重定向
- 调用RequestDispatcher.forward 方法实现请求分派(转发)
重定向
执行方式
response.sendRedirect("目标URL");
原理
- Servlet执行重定向时是向客户端返回302响应。并把“目标URL”当作响应消息头Location的值发送给客户端。
- 客户端浏览器接收到302响应后,会自动发起Location消息头指向的新地址的请求。并把新地址显示在地址栏中。
- Web容器针对这个新请求再作出响应。
特征
- 两次请求和响应。
- 最终请求地址显示在地址栏中。
- 第一个请求中的所携带数据在第二个Servlet中丢失。
适用于重定向到静态页面或一个更新数据的服务器操作
请求分派
执行方式
RequestDispatcher rd = request.getRequestDispatcher("目标URL").forward(request, response); //转发请求
原理
- 由Web容器把请求和响应对象传给下一个资源,下一个资源对客户端作出响应。
特征
- 只有一次请求和响应
- 浏览器地址栏上的URL没有任何变化。
- 请求中的数据不会丢失。
适用于带数据的跳转,如查询操作。
请求分派和重定向区别
最大区别是:
- 重定向由客户端来完成工作,而请求分派要求服务器上的某个Servlet来完成任务。
- 重定向会丢失请求对象中的数据。而请求分派不会。
注意:
- 重定向和请求分派中的新路径若以“/”开头,意义不同。
- 重定向中:/代表服务器根路径http://localhost:8080
- 请求分派中:/代表Web应用根路径(虚拟目录)http://localhost:8080/WebContextRoot
8. 利用请求域属性传递对象数据
ServletRequest接口中定义了几个方法
方法 | 描述 |
---|---|
void setAttribute(String name, Object obj) | 把指定名称的obj属性存放到请求域中 |
Object getAttribute(String name) | 从请求域中获取指定名称的属性 |
void removeAttribute(String name) | 把指定名称的obj属性从请求域中删除 |
- 这种存储在ServletRequest中的对象称之为请求域属性
- 属于同一个请求的多个处理模块之间可以通过请求域属性来传递对象数据。(请求分派)
9. ServletConfig(容器)
容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig对象(Servlet配置对象),容器会从部署描述文件(web.xml)中“读出”servlet初始化参数交给ServletConfig对象,然后再把ServletConfig对象传递给Servlet的init()方法。
web.xml配置
<servlet>
<servlet-name>initParamaterServlet</servlet-name>
<servlet-class>com.liqk.web.InitParamServlet</servlet-class>
<init-param>
<param-name>counter</param-name>
<param-value>100</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>initParamaterServlet</servlet-name>
<url-pattern>/getInitParameter.do</url-pattern>
</servlet-mapping>
在Servlet中获取初始化对象
//得到Servlet初始化参数对象
ServletConfig config=this.getServletConfig();
//获得指定名称的Servlet初始化参数的值
String counter=config.getInitParameter("counter");
10. ServletContext(应用上下文)
当容器部署某个Web应用程序之后,它会为每个Web应用程序建立一个ServletContext对象(Web应用上下文对象)。
你可以用ServletContext对象取得上下文初始化参数。—> ApplicationContextweb.xml 中配置
web.xml中的配置
<web-app>
<context-param>
<param-name>applicationName</param-name>
<param-value>Servlet在线网站</param-value>
</context-param>
<servlet> ....</servlet>
</web-app>
在Servlet中获取
//得到应用上下文对象
ServletContext context=this.getServletContext();
//获得指定名称的上下文初始化参数的值
String para=context.getInitParameter("applicationName");
SerlvetContext 充当全局作用域
ServletContext可以被认为是对于Web应用程序的一个整体性存储区域。每一个Web应用程序都具有一个ServletContext。存储在ServletContext之中的对象将一直被保留,除非是被删除。
存放在ServletContext对象中的属性(也叫应用上下文域属性)可以被该Web应用程序内的所有Servlet程序访问。
需要注意操作时的线程安全问题
提供的操作方法:
方法 | 描述 |
---|---|
void setAttribute(String name, Object obj) | 把指定名称的obj属性存放到应用上下文作用域中 |
Object getAttribute(String name) | 从应用上下文作用域中获取指定名称的属性 |
void removeAttribute(String name) | 把指定名称的obj属性从应用上下文作用域中删除 |
11. ServletConfig和ServletContext的区别
一个web应用只有一个ServletContext,部署Web应用时,容器会建立这一个ServletContext对象,这个上下文对Web应用中所有的Servlet和JSP都可用。
Web应用中的各个servlet/JSP都有自己的ServletConfig,它只对当前servlet有效
六、Session会话
1. 会话和会话状态
会话:同一个客户端与Web服务器之间发生的一系列请求和响应过程。
如:一个用户在某个网站上的整个购物过程。
会话状态:客户端与Web服务器在会话过程中产生的状态信息。
如:购物过程时,当前客户端所订购产品的数据。
借助会话状态,Web服务器能够把同一会话中的一系列的请求和响应过程关联起来,使得它们之间可以互相依赖和传递信息。
2. 创建会话对象(HttpSession)
HttpServletRequest中有两个方法可用于创建会话:
- public HttpSession getSession()
调用此方法时,Web容器会先检查客户端先前送出的请求是否有建立过HTTP会话;
如果没有:容器会新建一个会话对象,并赋予一个唯一的会话ID;
如果有:容器会根据客户请求中的会话ID找到相匹配的会话对象。 - public HttpSession getSession(boolean flag)
此方法的flag是用来指定是否有必要创建一个会话.
如:调用getSession(false)时,若客户先前没有建立过会话,则方法将返回null
3. HttpSession常用方法
方法签名 | 描述 |
---|---|
boolean isNew() | 判断该会话对象是不是一个新创建的会话 |
long getCreationTime() | 获取该Session创建的时间毫秒值(从1970-1-10:0:0) |
String getId() | 获取会话ID |
long getLastAccessedTime() | 获取最后一次访问此会话的时间毫秒值 |
long getMaxInactiveInterval() | 获取会话超时的时间秒值 |
ServletContext getServletContext() | 获取该会话所属的ServletContext对象 |
void setAttribute(String name, Object value)Object getAttribute(String name) voidAtt ib t (St i) | 根据指定名将对象数据存放(绑定)到会话中根据指定名从会话中获取相应属性根据指定名从会话中移除相应属性 |
removeAttribute(String name) | 从会话中移除相应属性 |
void invalidate() | 使会话失效 |
void setMaxInactiveInterval(int interval) | 设置会话超时的时间秒值也可以在web.xml内配置 |
4. 会话跟踪技术
有状态的会话是指Web服务器能够随时获取每个客户端跟服务器会话的状态信息。
HTTP协议是一种无状态的协议:浏览器主动发出一个请求,Web服务器被动地回应一个结果,不会保留客户的任何信息,因此服务器接收到来自某个浏览器发出的访问请求时,无法确定该浏览器以前的访问请求信息。
使用会话ID(JSESSIONID)来标识每次的请求消息以实现有状态的会话。
- Web服务器必须以某种方式把会话ID作为响应的一部分交给客户端
- 而客户端必须在每次请求时把会话ID作为一部分发回给服务器。
常用的会话跟踪技术:
- 通过“Cookie”技术在请求消息中进行传递会话ID。默认方式
- 通过“URL重写”技术使用请求URL把会话ID作为附加参数进行传递
- 通过“SSL”技术。安全套接层:使用HTTPS协议 ->加密的,有状态的
5. Cookie的特性
- 优点:Cookie在客户和服务器之间的传送都是自动进行的,不需要人为介入。
- 缺点:客户端浏览器可以禁用Cookie。这时自动的会话跟踪就失效了。
6. Session的结束
如果客户端主动要求结束会话,则可以调用HttpSession的invalidate()方法。
否则Web服务器将采用“超时限制”的办法来结束会话。
如果某个客户端在一定时间之内没有发出后续请求,Web服务器就认为客户端已经停止了活动,就会结束与该客户端的会话,并将与之对应的HttpSession对象变成垃圾。
在web.xml中可设置本应用所有会话的超时时间(分钟值)
<web-app...>
<session-config>
<session-timeout>30</session-timeout><!-- 分钟 -->
</session-config>
</web-app>
7. HttpSession的持久化
为了提高Web服务器内存资源的利用率,Web服务器通常将那些暂时不活动但未超时的HttpSession对象持久化到磁盘文件系统中保存,一旦服务器需要使用它们时,再将它们从文件系统中装载进内存。
默认的存储文件为:
CATALINA_HOME/work/Catalina/主机/应用名/SESSIONS.ser
- 存储在HttpSession中的每个属性对象必须是可序列化的。即对应的类必须实现java.io.Serializable接口。