第 02 章 JSP

第 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.jspJSP。

工商银行

工作原理

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才会执行编译这个过程。

JSP执行过程

在Servlet中,所谓的Html就是输出将HTML标签输出到浏览器,由浏览器下载下来,才能执行。就像其他普通的网页一样,您的浏览器发送一个 HTTP 请求给服务器。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%="hello jsp!啊哈哈"%>
    <%out.println("我就是看看怎么输出字符串");%>


  1. Web 服务器识别出这是一个对 JSP 网页的请求,并且将该请求传递给 JSP 引擎。通过使用 URL解析或者 .jsp 文件来完成。
  2. JSP 引擎从磁盘中载入 JSP 文件,然后将它们转化为 Servlet。这种转化只是简单地将所有模板文本改用 println() 语句,并且将所有的 JSP 元素转化成 Java 代码。
  3. JSP 引擎将 Servlet 编译成可执行类,并且将原始请求传递给 Servlet 引擎。
  4. Web 服务器的某组件将会调用 Servlet 引擎,然后载入并执行 Servlet 类。在执行过程中,Servlet 产生 HTML 格式的输出并将其内嵌于 HTTP response 中上交给 Web 服务器。
  5. Web 服务器以静态 HTML 网页的形式将 HTTP response 返回到您的浏览器中。
  6. 最终,Web 浏览器处理 HTTP response 中动态产生的HTML网页,就好像在处理静态网页一样。

【TIPS】

  1. 在开发过程中,修改静态资源和JSP,是不需要重启服务的。在Idea中,只需要使用快捷键ctrl+D,如下图,选择update classes and resources即可。

    Tips 1

  2. Idea 运行Tomcat后,编译JSP文件存放的目录在/Users/{用户名}/Library/Caches/JetBrains/IntelliJIdea{版本号}/tomcat/{项目名称}/work/Catalina/localhost/webapp_serlet/org/apache/jsp/(mac系统中)。

  3. 在使用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服务即可。

  4. 关于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文件的行数,如下图所示:


    500错误

关于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%>


  1. 是在page指令中设置:
    1. <%@ page pageEncoding="UTF-8" language="java" %>是设置java文件的编码,指令中所设置的<%@ page pageEncoding="UTF-8" %>是页面(或者说是index_jsp.java这个java文件编码格式)。
    2. <%@ page contentType="text/html;charset=UTF-8" %>是设置响应输出流的编码格式,在index_jsp.java编译的java文件中,有一行代码response.setContentType("text/html;charset=UTF-8");,其中response对象设置的contentType,属于HTTP的响应头。是服务器往客户端响应(write()往外输出流的时候)是以什么样的编码格式输出。
  2. 是在HTML页面中的meta标签中设置,此处为浏览器从应用服务中下载页面后,以什么样的编码格式读取文件,展示给浏览器客户端钱前的用户。

比如下面的乱码形式:

  1. pageEncoding设置错误导致的乱码
    关于pageEncoding
  2. contentType响应输出流编码格式设置错误导致的乱码
    contentType响应输出流乱码
  3. meta设置错误的编码,没有造成乱码。
    meta设置错误的编码

为了规避乱码,三个编码应该保持一致。

关于out

  • out对象
    • out对象是JSP的内置对象
      • 无需实例化即可使用
    • 实现数据的输出显示
  • out对象的方法
属性 说明
print 向页面输出显示
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。所以在表单中,如果进行中文传输,将会有乱码的现象发生。下面将初步介绍如何解决中乱码的问题。

  1. POST请求解决中文乱码,使用request.setCharaterEncoding("UTF-8")来解决中文乱码。
  2. get请求中解决中文乱码方式有以下3种:
    1. 对于某个获取参数的进行重新编码,如String str = new String(request.getParamter("user").getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8)。这种方式治标不治本。解决不了根本的乱码问题。
    2. 下面介绍的两种方式,均是在tomcat配置目录下的conf/server.xml中进行配置
      1. 对tomcat目录中的配置conf/server.xml添加配置URIEncoding="UTF-8"这种方式很粗暴。将影响一些不需要的转码字符也被转码。

        
        
      2. 在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对象。需要将返回值强转为自己需要的类型。


注意:

  1. 使用属性值的时候要做非空判断,否则会出现空指针异常。
  2. 他的返回值类型是Object类型,需要做数据类型的转换。

Session对象

sesssion工作方式

在客户端(一般是指浏览器)和服务器之间建立会话后(建立长连接[1]),会在该会话当中,产生若干次请求和响应。

客户端和服务器之间的交互,只可能是客户端对服务器进行轮训,而服务器时无法主动寻找客户端进行数据推送的。

Session的特点
  1. Session可以保存属性,保留数据(比如,记录用户的登录状态)
    1. 第一次请求到达服务器后,服务器将自动生成一个sessionId,并将该sessionId作为本地会话的唯一凭证(将session返回给浏览器)。以后(第二次请求开始)该会话的每次请求,都会携带sessionId。
    2. 在正常且不超时的情况下,只要浏览器不关闭,session就不会中断。
    3. Session可以作为服务器和客户端的一次会话缓存
    4. Session为客户端用户独享。
    5. Session默认无操作的情况下保留sessionId 30分钟(一般情况下不会去修改)。
  2. 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();

关于清除数据:

  1. 设置会话失效session.invalidate();
  2. 移除会话的某个属性:session.removeAttribute(String attributeName);

Application对象

比如实现统计每个用户访问次数

  1. 整个服务共享数据,所有的用户都可以获取这里的数据

Cookie

  1. 将数据保存在客户端
  2. 保存的上限是7天
  3. 存在的极大的安全的隐患
  4. 用户是可以禁止Cookie的
  5. Cookie第一次请求服务端,如果服务端没有生成SessionId,将会由客户端生成一个SessionId交给服务器。
  6. 不能将敏感的数据存放在cookie里面。

对象的作用域

对象 作用域[2]
Page 只作用域当前的JSP(Servlet中不存在JSP)
Request 作用于一次请求
Session 作用于一次会话
Application 作用于整个工程

转发和重定向

转发

转发方式

转发有两种方式:

  1. 使用Request中的方法RequestDispatcher对象,语法如下:
    // request对象和response对象
    request.getRequestDispatcher("url").forward(request, response)
    
  2. 使用forword()方法进行重定向。语法如下所示:
    
    

转发工作方式

转发工作方式

从上图可以看出,转发是客户端发送一次请求到服务器后,服务器交给JSP页面(但是当前JSP页面无法处理),将把本地请求转交给其他的URL或JSP页面进行处理。可以在转发的地址中获取请求的参数(可直接获取"getParameter(String paramter)")。

总结如下:

  1. 所有的数据流转,全部再后台完成。
  2. 用户只有一次请求,并获得一次响应。
  3. URL是有没有任何变化的。
  4. 转发是将请求和响应一并带走,也就意味着他可以获取原本request对象中所有的参数和数据。
  5. 转发是不能转发到工程(仅限定本地应用)的外部资源的(本质是从一个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);

重定向工作方式

重定向工作方式
  1. 转发一次,将会通过响应告诉客户端重新请求服务器。
  2. 原本的requestresponse全部丢失。将会产生新的requestresponse
  3. 重定向既不携带请求的参数也不携带属性。如果需要携带参数,只能通过url传参或者SESSION等其他方式进行传参。
  4. 重定向是可以重定向至任意资源的。
  5. 重定向将导致URL的变化。

转发和重定向的区别

URL变化
重新发出请求 不会
是否携带请求
目标URL要求 仅本Web应用 任意URL


重定向是客户端行为,转发是服务器行为!

关于Request、Session以及Application的对比

requestsessionapplication者三个对象都可以存储属性。

对象 生命周期
Request 存储的数据仅在一个请求中可用
Session 存储的数据在一个会话有效期内可用
Application 存储的数据在整个Web项目中可用

  1. 长连接是服务器与服务器之间建立通讯的通道,其最底层实现就是socket。可以实现服务端与客户端只要通讯不中断,那么服务器可以推送数据至客户端,客户端也可以主动请求服务端。 ↩

  2. 作用域是指当前数据可以作用的范围(简单的判断方法,只要有setAttribute以及getAttribute这两个方法一般属于作用域)。 ↩

你可能感兴趣的:(第 02 章 JSP)