第 02 章 JSP
该部分代码在webapp-serlet中的jsp页面中展示;
JSP概述
什么叫JSP?JSP的全称叫(Java Server Page),是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%
开头以%>
结束。
JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。
简单理解有以下两点:
- 运行在服务器端的Java页面
- 使用HTML嵌套Java代码实现。
JSP最大优势就是安全,这是前后端分离无法做到的。这是因为JSP有一个编码的过程,这个过程可以阻挡很多攻击。前后端分离只是一个趋势,并不能代表JSP是弱势的。比如下面的图片,其注册页面仍是https://epass.icbc.com.cn/regist/regist_index.jsp
JSP。
工作原理
浏览器通过网络访问服务器后,服务器需要对JSP页面进行编译,编译成类似HTML文件,而实际上最终把它变成Java代码,因为只有Java才能访问数据库等其他操作。
关于如何查看JSP编译后的文件,请看【TIP】中的第2点。
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
// 获取响应输出流对象为null
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
// 设置响应输出流的ContentType类型,并设置编码为UTF8。
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
// 获取响应输出流对象
out = pageContext.getOut();
_jspx_out = out;
// 设置输出字符串结构,也就是HTML的结构
out.write("\n");
out.write("\n");
out.write("\n");
out.write("\n");
out.write(" Title \n");
out.write("\n");
out.write("\n");
out.write(" ");
out.print("hello jsp!啊哈哈");
out.write("\n");
out.write("\n");
out.write("\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
上面一段代码就是JSP页面编译后的结果。所以JSP的本质就是Java代码,就是Servlet。在正常请求后,JSP才会执行编译这个过程。
在Servlet中,所谓的Html就是输出将HTML标签输出到浏览器,由浏览器下载下来,才能执行。就像其他普通的网页一样,您的浏览器发送一个 HTTP 请求给服务器。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%="hello jsp!啊哈哈"%>
<%out.println("我就是看看怎么输出字符串");%>
- Web 服务器识别出这是一个对 JSP 网页的请求,并且将该请求传递给 JSP 引擎。通过使用 URL解析或者 .jsp 文件来完成。
- JSP 引擎从磁盘中载入 JSP 文件,然后将它们转化为 Servlet。这种转化只是简单地将所有模板文本改用 println() 语句,并且将所有的 JSP 元素转化成 Java 代码。
- JSP 引擎将 Servlet 编译成可执行类,并且将原始请求传递给 Servlet 引擎。
- Web 服务器的某组件将会调用 Servlet 引擎,然后载入并执行 Servlet 类。在执行过程中,Servlet 产生 HTML 格式的输出并将其内嵌于 HTTP response 中上交给 Web 服务器。
- Web 服务器以静态 HTML 网页的形式将 HTTP response 返回到您的浏览器中。
- 最终,Web 浏览器处理 HTTP response 中动态产生的HTML网页,就好像在处理静态网页一样。
【TIPS】
-
在开发过程中,修改静态资源和JSP,是不需要重启服务的。在Idea中,只需要使用快捷键
ctrl
+D
,如下图,选择update classes and resources
即可。
Idea 运行Tomcat后,编译JSP文件存放的目录在
/Users/{用户名}/Library/Caches/JetBrains/IntelliJIdea{版本号}/tomcat/{项目名称}/work/Catalina/localhost/webapp_serlet/org/apache/jsp/
(mac系统中)。-
在使用tomcat 9.0版本时,发了一个错误(警告),错误如以下:
org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。
只需要将Tomcat下面的配置文件目录conf/catalina.properties
中的tomcat.util.scan.StandardJarScanFilter.jarsToSkip=/
改成*.jar
即可,如下所示tomcat.util.scan.StandardJarScanFilter.jarsToSkip=*.jar annotations-api.jar,\ ant-junit*.jar,\ ant-launcher.jar,\ ... xmlParserAPIs-*.jar,\ xmlParserAPIs.jar,\ xom-*.jar
再重启tomcat服务即可。
-
关于Servlet编译JSP的命令规范,首先将
index.jsp
文件找到后,编译后的文件则命名为index_jsp.java
文件以及index_jsp.class
文件,如下图所示。
JSP实现输出
该部分代码在webapp-serlet中的demo01中展示;
关于JSP的局部申明与全局申明
-
<% code %>
是申明局部变量;局部指的是jspjava文件中的_jspService()
方法内。- 不可以对变量使用修饰符。
- 不可以定义方法。
-
<%! code %>
是申明全局变量;- 申明全局变量,可以在当前的页面任意位置进行调用;
- 可以创建对应的方法,以及变量。
比如,在下面的jsp页面中,
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
String str = "欢迎来到JSP World!";
for (int i = 0; i < 3; i++) {
out.println(""+str+"");
test();
}
%>
<%-- 等价于out.println(str);--%>
<%=str%>
<%=PATH%>
<%-- 申明全局变量 --%>
<%!
<%-- 申明全局变量 --%>
private static final String PATH=System.lineSeparator();
<%-- 申明全局方法 --%>
public void test(){
System.out.println("这是一个全局方法!");
}
%>
下面将Servlet引擎编译后的JSP,indexjsp.java文件如下:
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
// 申明的全局变量
private static final String PATH=System.lineSeparator();
// 申明的全局方法
public void test(){
System.out.println("这是一个全局方法!");
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
// 此处省略部分代码
....
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("\n");
out.write("\n");
out.write("\n");
out.write(" Title \n");
out.write("\n");
out.write("\n");
out.write(" \n");
out.write(" ");
String str = "欢迎来到JSP World!";
for (int i = 0; i < 3; i++) {
out.println(""+str+"");
test();
}
out.write("\n");
out.write("
\n");
out.write(" ");
out.write("\n");
out.write(" ");
out.print(str);
out.write("\n");
out.write(" ");
out.print(PATH);
out.write("\n");
out.write("\n");
out.write(" ");
out.write("\n");
out.write("\n");
out.write("\n");
} catch (java.lang.Throwable t) {
......
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
从上编译的文件,可以看出我们之前刚刚所提的局部变量与全局变量的问题。局部变量是在_jspService()
方法内的,而全局变量则是index_jsp
类中的。
关于应用服务状态
404错误
404错误---找不到访问的页面或资源
- 运行时,URL输入错误
- 将页面放在WEB-INF下
- 外部启动Tomcat,未部署项目
500错误
500错误----JSP页面代码有误;
- JSP页面代码有错误
- 页面无法显示
-
未启动Tomcat
jsp报异常,异常的分布包含在2个地方,一个是JSP页面文件当中的行数,还有一个是生成的_jsp.java文件的行数,如下图所示:
关于Page指令
通过属性定义了JSP的特性,实现与JSP容器的通信。
语法
<%@ page language="属性值" import="属性值" contentType="属性值"%>
属性 | 说明 |
---|---|
language | 指定JSP页面使用的脚本语言 |
import | 通过该属性来引用脚本语言中使用到的类文件 |
contentType | 用来指定页面的MIME类型,以及字符编码方式 |
示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.ermao.servlet.entity.*" %>
Title
<%Person person = new Person();%>
<%=person%>
关于编码
JSP有三个地方设置编码,如下代码所示:
<%@ page pageEncoding="UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="com.ermao.servlet.entity.*" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
Title
<%
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
Date date = new Date();
String dateStr = simpleDateFormat.format(date);
%>
<%Person person = new Person();%>
<%=person%>
<%=dateStr%>
- 是在
page
指令中设置:-
<%@ page pageEncoding="UTF-8" language="java" %>
是设置java文件的编码,指令中所设置的<%@ page pageEncoding="UTF-8" %>
是页面(或者说是index_jsp.java
这个java文件编码格式)。 -
<%@ page contentType="text/html;charset=UTF-8" %>
是设置响应输出流的编码格式,在index_jsp.java
编译的java文件中,有一行代码response.setContentType("text/html;charset=UTF-8");
,其中response
对象设置的contentType
,属于HTTP的响应头。是服务器往客户端响应(write()
往外输出流的时候)是以什么样的编码格式输出。
-
- 是在HTML页面中的
meta
标签中设置,此处为浏览器从应用服务中下载页面后,以什么样的编码格式读取文件,展示给浏览器客户端钱前的用户。
比如下面的乱码形式:
-
pageEncoding
设置错误导致的乱码
-
contentType
响应输出流编码格式设置错误导致的乱码
-
meta
设置错误的编码,没有造成乱码。
为了规避乱码,三个编码应该保持一致。
关于out
- out对象
- out对象是JSP的内置对象
- 无需实例化即可使用
- 实现数据的输出显示
- out对象是JSP的内置对象
- out对象的方法
属性 | 说明 |
---|---|
向页面输出显示 | |
println | 向页面输出显示,在结尾处添加换行 |
jsp 最终通过响应输出
out
输出(输出一个text文本),浏览器读取的时候,首先通过inputStream,然后read(text)变成一个File f=File(in)
。然后浏览器通过windows.load(f)
加载文件,然后再是document()
输出。
关于JSP内置对象
以下内容是JSP最核心,最重要,也是所有交互层概念当中最最需要掌握的地方。
JSP本质
在上面的内容中,已经提到JSP的本质就是Java。
JSP其实本质是Java的Servlet,将HTML的编码已文本流的方式交给客户端,在HTML当中我们实际看到的就是一个普通的前端页面。
JSP内置对象
该部分代码在webapp-serlet中的demo02中展示;
JSP内置对象(隐式对象)是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。
JSP所支持的九大内置对象,如下表,其中标记的对象必须重点掌握。
对象 | 描述 | 对象作用域 |
---|---|---|
request | HttpServletRequest 接口的实例 | 局部变量 |
response | 响应对象,HttpServletResponse 接口的实例 | 局部变量 |
out | JspWriter类的实例,用于把结果输出至网页上 | |
session | HttpSession类的实例,会话对象,是从application对象中获取。 | 局部变量 |
application | 应用程序对象,ServletContext类的实例,与应用上下文有关 | 局部变量 |
config | ServletConfig类的实例,配置对象 | |
pageContext | PageContext类的实例,页面上下文对象,提供对JSP页面所有对象以及命名空间的访问 | |
page | 页面对象,类似于Java类中的this关键字,只作用于JSP中。 | |
Exception | Exception类的对象,代表发生错误的JSP页面中对应的异常对象 |
Request对象
当浏览器向服务器发起请求,那么浏览器本次请求所携带的所有信息,都包含在Request对象中。
request对象是javax.servlet.http.HttpServletRequest
类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。
request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。
比如下面两个JSP页面,register.jsp
(是一个注册页面)以及register-service.jsp
(服务端的一个页面)。上述内容均属于引入说明。
register.jsp
页面
<%-- 设置编码格式 --%>
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" language="java" %>
测试注册页面
register-service.jsp
页面
<%-- 设置编码格式 --%>
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
String user = request.getParameter("user");
String password = request.getParameter("password");
%>
<%=user%>
<%=password%>
当请求抵达指定页面后,需要从Request对象中的getParamter(String paramterName)
获取请求参数。
获取复数形式的选项则使用getParameterValues(String paramterName)
,比如checkbox等。
关于GET与POST请求
在Http请求中,存在两种请求数据的方式,如下所示:
- GET(默认):希望从服务器获取数据
- POST:希望向服务器提交数据
比较项 | get | post |
---|---|---|
参数出现在URL中 | 是 | 否 |
长度限制 | 有 | 无 |
安全性 | URL低(暴露请求参数) | URL安全高(未直接暴露请求参数) |
URL可传播 | 是 | 否 |
而Http请求使用的Http协议,但是Http协议又是明文协议,而Http的密文协议就是Https,使用SSL进行加密。
请求类型的安全不是指Http的报文的安全,而是请求的参数是否暴露在URL地址中。
Request常用方法
方法名称 | 说明 |
---|---|
String getParameter(String name) |
根据表单组件名称获取提交数据 |
String[ ] getParameterValues(String name) |
获取表单组件对应多个值时的请求数据,如checkbox等 |
void setCharacterEncoding(String charset) |
指定每个请求的编码 |
RequestDispatcher getRequestDispatcher(String path) |
返回一个RequestDispatcher对象,该对象的forward( ) 方法用于转发请求 |
关于提交数据中文乱码
该部分代码在webapp-serlet中的demo02中展示;
JSP默认的数据传输编码是ISO-8859-1
,而不是UTF-8
。所以在表单中,如果进行中文传输,将会有乱码的现象发生。下面将初步介绍如何解决中乱码的问题。
- POST请求解决中文乱码,使用
request.setCharaterEncoding("UTF-8")
来解决中文乱码。 - get请求中解决中文乱码方式有以下3种:
- 对于某个获取参数的进行重新编码,如
String str = new String(request.getParamter("user").getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8)
。这种方式治标不治本。解决不了根本的乱码问题。 - 下面介绍的两种方式,均是在tomcat配置目录下的
conf/server.xml
中进行配置
。-
对tomcat目录中的配置
conf/server.xml
添加配置URIEncoding="UTF-8"
这种方式很粗暴。将影响一些不需要的转码字符也被转码。 -
在tomcat配置目录下的
conf/server.xml
还有一种GET请求转码,就是添加useBodyEncodingForURI="true"
只有配置了该属性才会在GET请求中才会生效。不对项目做任何的字符集限制,可以针对性对request.setCharaterEncoding("UTF-8")
。如果在未设置useBodyEncodingForURI="true"
的前提下,单独使用request.setCharaterEncoding("UTF-8")
将是不会对GET传参进行转码解码的,只会对POST的传参进行解码转码。需要配合进行使用
request.setCharaterEncoding("UTF-8")
;比如,某些页面需要单独设置其他编码,那么就可以通过这种方式实现。
-
- 对于某个获取参数的进行重新编码,如
JSP解决中乱码的总体原则就是:保证整个项目当中,所有文件(文件、文件流)的字符集统一!
属性转交
该部分代码在webapp-serlet中的demo03中展示;验证属性的转交,页面转交过程。是又
index.jsp
输入表单,get_form_service.jsp
接受表单数据,再设置属性,get_attribute.jsp
来获取属性。同时结合转发和重定向。
当请求到达后台后,可以从request.getParameter(String param)
拿取一次数据,而其他的JSP页面则无法获取到本次的传递的参数,除非是同一个request请求,否则无法获取相关的参数。如果其他JSP页面需要进行数据流转(数据处理)时,需要将数据发送出去,那么将处理后的数据当做request对象中的属性保存(通过设置request.setAttribute(String name,Object obj)
),方便数据的传输。其他的JSP页面则通过request.getAttribute(String name)
来获取之前JSP处理后的数据。比如,判断是否登录(也可以通过Session来完成)。
当从Attribute
中获取属性时,必须强转返回数据。因为setAttribute(String name ,Object obj)
。而getAttribute(String name)
时,则返回的是Object
对象。需要将返回值强转为自己需要的类型。
注意:
- 使用属性值的时候要做非空判断,否则会出现空指针异常。
- 他的返回值类型是Object类型,需要做数据类型的转换。
Session对象
在客户端(一般是指浏览器)和服务器之间建立会话后(建立长连接[1]),会在该会话当中,产生若干次请求和响应。
客户端和服务器之间的交互,只可能是客户端对服务器进行轮训,而服务器时无法主动寻找客户端进行数据推送的。
Session的特点
- Session可以保存属性,保留数据(比如,记录用户的登录状态)
- 第一次请求到达服务器后,服务器将自动生成一个sessionId,并将该sessionId作为本地会话的唯一凭证(将session返回给浏览器)。以后(第二次请求开始)该会话的每次请求,都会携带sessionId。
- 在正常且不超时的情况下,只要浏览器不关闭,session就不会中断。
- Session可以作为服务器和客户端的一次会话缓存
- Session为客户端用户独享。
- Session默认无操作的情况下保留sessionId 30分钟(一般情况下不会去修改)。
- session的数据是在服务器端的,服务器保存的会话数据量(产生数据冗余)会越来越大,从而导致性能问题。
若Session没有清理机制,会导致性能问题或服务器崩溃,所有在调用Session时,当会话结束后,程序应该做到以下两点:
- 程序主动清除session数据,比如退出登录时,清楚sessionId等数据。
- 服务器主动清除长时间没有再次发出请求的session。
Session的调用
调用session的设置方法。
public void setAttribute(String name, Object value)
session.setAttribute("userName", "张三丰");
调用设置session的属性的方法。
public Object getAttribute(String name);
userName=(String)session.getAttribute("userName");
获取sessionId。
public String getId();
session.getId();
关于清除数据:
- 设置会话失效
session.invalidate();
- 移除会话的某个属性:
session.removeAttribute(String attributeName);
Application对象
比如实现统计每个用户访问次数
- 整个服务共享数据,所有的用户都可以获取这里的数据
Cookie
- 将数据保存在客户端;
- 保存的上限是7天
- 存在的极大的安全的隐患
- 用户是可以禁止Cookie的
- Cookie第一次请求服务端,如果服务端没有生成SessionId,将会由客户端生成一个SessionId交给服务器。
- 不能将敏感的数据存放在cookie里面。
对象的作用域
对象 | 作用域[2] |
---|---|
Page | 只作用域当前的JSP(Servlet中不存在JSP) |
Request | 作用于一次请求 |
Session | 作用于一次会话 |
Application | 作用于整个工程 |
转发和重定向
转发
转发方式
转发有两种方式:
- 使用
Request
中的方法RequestDispatcher
对象,语法如下:// request对象和response对象 request.getRequestDispatcher("url").forward(request, response)
- 使用
forword()
方法进行重定向。语法如下所示:
转发工作方式
从上图可以看出,转发是客户端发送一次请求到服务器后,服务器交给JSP页面(但是当前JSP页面无法处理),将把本地请求转交给其他的URL或JSP页面进行处理。可以在转发的地址中获取请求的参数(可直接获取"getParameter(String paramter)
")。
总结如下:
- 所有的数据流转,全部再后台完成。
- 用户只有一次请求,并获得一次响应。
- URL是有没有任何变化的。
- 转发是将请求和响应一并带走,也就意味着他可以获取原本
request
对象中所有的参数和数据。 - 转发是不能转发到工程(仅限定本地应用)的外部资源的(本质是从一个servlet跳转到另一个servlet)。
重定向
重定向方式
通过调用response
对象中的sendRedirect(String url)
方法实现。如下所示:
response.sendRedirect(url);
经过查阅资料,再提供下面两种重定向的实现。
// 第一种重定向方式:
// 下面的参数中,
// refresh代表刷新页面,
// 5代表间隔多久刷新页面(单位:秒)
// RedirectUrl代表的是重定向的地址
response.setHeader("refresh","5;URL=RedirectUrl")
// 第二种重定向方式:
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", RedirectUrl);
重定向工作方式
- 转发一次,将会通过响应告诉客户端重新请求服务器。
- 原本的
request
和response
全部丢失。将会产生新的request
和response
。 - 重定向既不携带请求的参数也不携带属性。如果需要携带参数,只能通过
url
传参或者SESSION
等其他方式进行传参。 - 重定向是可以重定向至任意资源的。
- 重定向将导致URL的变化。
转发和重定向的区别
URL变化 | 否 | 是 |
---|---|---|
重新发出请求 | 不会 | 会 |
是否携带请求 | 是 | 否 |
目标URL要求 | 仅本Web应用 | 任意URL |
重定向是客户端行为,转发是服务器行为!
关于Request、Session以及Application的对比
request
、session
、application
者三个对象都可以存储属性。
对象 | 生命周期 |
---|---|
Request | 存储的数据仅在一个请求中可用 |
Session | 存储的数据在一个会话有效期内可用 |
Application | 存储的数据在整个Web项目中可用 |
-
长连接是服务器与服务器之间建立通讯的通道,其最底层实现就是socket。可以实现服务端与客户端只要通讯不中断,那么服务器可以推送数据至客户端,客户端也可以主动请求服务端。 ↩
-
作用域是指当前数据可以作用的范围(简单的判断方法,只要有setAttribute以及getAttribute这两个方法一般属于作用域)。 ↩