详谈JSP执行原理、生命周期、语法、指令、动作标签、九大内置对象(JSP 全家桶)

一、JSP 结构

以下是表明Web服务器是如何使用JSP来创建网页的:

  • 用户在浏览器上发送一个HTTP请求给服务器,web服务器会判断是否是JSP网页请求,如果是则启动JSP引擎。
  • JSP引擎从磁盘中载入JSP文件,然后将它们翻译为servlet文件并将servlet编译成可执行类,再将原始请求传递给servlet引擎。这种转化只是简单地将所有模板文本改用println()语句,并且将所有的JSP元素转化成Java代码。
  • web服务器的某组件将会调用servlet引擎,然后载入并执行servlet类。在执行过程中,servlet产生HTML格式的输出并将其内嵌于HTTP response中上交给Web服务器。
  • web服务器以静态HTML网页的形式将HTTP response返回到您的浏览器中。
  • 最后,web浏览器处理HTTP response中动态产生的HTML网页,就好像在处理静态网页一样。
    在这里插入图片描述

二、JSP执行原理及本质

  1. 用户在浏览器地址栏上输入http://localhost:8080/hcz/index.jsp,web服务器判断用户请求的资源是hcz应用中index.jsp页面,web服务器在hcz应用中找到index.jsp
  2. 启动JSP引擎(是Tomcat服务器内置的一个JSP翻译引擎,专门负责翻译JSP文件,编译java源文件),将index.jsp翻译成index_jsp.java文件,并且将index_jsp.java文件编译生成index_jsp.class字节码文件,将其存储在Tomcat服务器work目录中。
  3. index_jsp.class类继承了HttpJspBase,HttpJspBase继承了HttpServlet,所以JSP本质上就是Servlet,和Servlet完全相同。
  4. 只有用户第一次访问这个JSP或者JSP页面被修改了,才会重新翻译。JSP有三个阶段:翻译(一次),编译(一次),运行(多次)。JSP更改,不需要重启服务器,也不需要重新部署项目。
  5. Jsp和Servlet本质上没有区别,但是JSP和Servlet它们的主要职责是有区别的:JSP主要是提取数据做页面展示,而Servlet主要完成业务逻辑处理以及资源跳转。Servlet是Controller(控制层),JSP是View(展示层)。
  6. 在JSP文件中编写的所有HTML、CSS、Javascript,对于JSP来说,只是普通的字符串,被翻译成:out.writer("…");

实例代码:执行JSP文件后翻译为Java文件的源代码是怎么样的?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <meta charset="UTF-8">
    <title>jsp页面</title>
  </head>
  <body>
    This is my JSP page. 666888<br>
           账号:<input type="text" name="username"><br>
           密码:<input type="text" name="password"><br>
        <input type="submit" value="提交">
        <%
         System.out.println("666888");
         %>
  </body>
</html>
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports { 
    public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException { 
      
      out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
      out.write("<html>\r\n");
      out.write("  <head>\r\n");
      out.write("    <base href=\"");
      out.print(basePath);
      out.write("\">\r\n");
      out.write("    <meta charset=\"UTF-8\">\r\n");
      out.write("    <title>jsp页面</title>\r\n");
      out.write("  </head>\r\n");
      out.write("  <body>\r\n");
      out.write("    This is my JSP page. 666888<br>\r\n");
      out.write("           账号:<input type=\"text\" name=\"username\"><br>\r\n");
      out.write("           密码:<input type=\"text\" name=\"password\"><br>\r\n");
      out.write("        <input type=\"submit\" value=\"提交\">\r\n");
      out.write("        ");
      System.out.println("666888");
      out.write("\r\n");
      out.write("  </body>\r\n");
      out.write("</html>\r\n");
     }
}

三、JSP生命周期

JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

  • 编译阶段
    当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。

编译的过程包括三个步骤

  • 解析JSP文件
  • 将JSP文件转换为servlet
  • 编译servlet
  • 初始化阶段
    加载与JSP对应的servlet类,创建其实例,并调用它的初始化_jspInit()方法
public void _jspInit(){
  // 初始化代码
}

一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在_jspInit()方法中初始化数据库连接、打开文件和创建查询表。

  • 执行阶段
    这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。
    当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。
    _jspService()方法需要一个HttpServletRequest对象和一个HttpServletResponse对象作为它的参数,就像下面这样:
public void _jspService(HttpServletRequest request,HttpServletResponse response)
{
   // 服务端处理代码
}
  • 销毁阶段
    调用与JSP对应的servlet实例的销毁方法_jspDestroy(),然后销毁servlet实例
public void jspDestroy()
{
   // 清理代码
}

以上通过描述JSP的生命周期,发现和servlet生命周期非常相似,下面给出图示:
在这里插入图片描述

四、JSP语法

JSP文件以.jsp/.jspx结尾,通常存放在和HTML资源同级目录中,在JSP文件中编写的普通字符串,以后翻译成Servlet的service方法中的 out.write() 将该字符串响应给浏览器。所以我们必须在JSP文件中编写一些特殊的符号,和jsp文件中的普通文本加以区别,这样jsp引擎就会根据不能的符号将其翻译到Servlet类中的不同位置。

1. 脚本程序(scriptlet)

脚本程序的语法格式:

<% 代码片段 %>
  • 在jsp文件中使用 <% %>,出现在该符号内的java程序翻译之后会被存放在Servlet的service方法中。
  • 所以在该符号内只能编写java语句或者定义局部内部类(通常很少使用局部内部类),每一个java语句以 “;” 结尾,在这个符号中的程序大家就当做在service方法中编程一样就行了。
  • 在该符号中声明的变量属于局部变量,不能使用访问控制权限修饰符修饰,所以在service方法中不能编写实例变量、不能编写方法、不能编写静态语句块。
<%-- 以下程序编译无法通过 --%>
<%--
    public String username;
--%>

<%--
    public void m1(){
    
    }
--%>

<%--
    static{
    
    }
--%>
  • 小脚本的数量随意,可以多个,小脚本中编写java程序出现在service方法中,service方法的代码是有执行顺序的,所以小脚本中的程序也是有顺序的。编写以下JSP文件:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
    int i = 10;
 %>
<html>
    <%
        System.out.println(i);
    %>
  <head>
    <%
        double d = 3.0;
    %>
    <meta charset="UTF-8">
    <title>jsp页面</title>
    <%
        System.out.println(d + i);
    %>
  </head>
  <body>
    This is my JSP page<br>
         <%
            System.out.println(d*i);
         %>
        <% 
            out.println("Your IP address is " + request.getRemoteAddr()); 
        %>
  </body>
</html>
<%
    String ename = "king";
    System.out.println("ename = " + ename);
%>

其经过JSP引擎翻译后成Servlet的service方法变为:

public class index_jsp extends HttpJspBase{
   public void _jspInit(){
   }
   public void _jspService(HttpServletRequest request,HttpServletResponse response){
   	
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");

    int i = 10;
 
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("\t");

        System.out.println(i);
    
      out.write("\r\n");
      out.write("  <head>\r\n");
      out.write("  \t");

        double d = 3.0;
    
      out.write("\r\n");
      out.write("    <meta charset=\"UTF-8\">\r\n");
      out.write("    <title>jsp页面</title>\r\n");
      out.write("    ");

        System.out.println(d + i);
    
      out.write("\r\n");
      out.write("  </head>\r\n");
      out.write("  <body>\r\n");
      out.write("    This is my JSP page<br>\r\n");
      out.write("    \t ");

            System.out.println(d*i);
         
      out.write("\r\n");
      out.write("        ");
 
            out.println("Your IP address is " + request.getRemoteAddr()); 
        
      out.write("\r\n");
      out.write("  </body>\r\n");
      out.write("</html>\r\n");

    String ename = "king";
    System.out.println("ename = " + ename);
   }
}
2. JSP声明(declaration)

声明的语法格式:

<%! declaration; [ declaration; ]+ ... %>
  • 在jsp文件中使用 <%! %> ,出现在该符号内的java程序翻译之后会被存放在和Servlet的service方法并列的位置上
  • 在该符号内声明静态变量、静态方法、静态代码块、实例代码块、实例变量、实例方法,大家就当做在类体中直接编码就可以了,所以声明的变量、方法都是可以使用访问控制权限修饰符修饰的。
  • 声明块中不能直接编写java语句,除非是变量的声明。例如:

<%!
    //java语句不能直接出现在类体中
    //System.out.println("Hello World!");

    public void doSome(){
        System.out.println("do some!");
    }
%>

实例代码:模拟JSP文件执行后在Servlet的service方法中的执行顺序是什么样的


<%@page contentType="text/html; charset=UTF-8"%>
<%
    doSome();
%>
<%!
    int i = 100;
%>
<%
    //java语句不能直接出现在类体中
    //System.out.println("Hello World!");

    public void doSome(){
        System.out.println("do some!");
    }
%>
<%
    System.out.println("servlet's service method execute!");
%>
<%!
    static{
        System.out.println("Class Loader!");
    }
%>
<%
    int j = 100;
%>
<%!
    public static void doOther(){
        System.out.println("do other!");
    }
%>
<%
    System.out.println("j = " + j);
    System.out.println("i = " + i);
%>

其经过JSP引擎翻译后成Servlet的service方法变为:

public class index_jsp extends HttpJspBase{
   int i = 100;
   public void doSome(){
  	System.out.println("do some!");
  }
  static{
  	System.out.println("Class Loader!");
  }
  public static void doOther(){
  	System.out.println("do other!");
  }
   public void _jspService(HttpServletRequest request,HttpServletResponse response){
   	dosome();
   	System.out.println("servlet's service method execute!");
   	int j = 100;
   	System.out.println("j = " + j);
 	System.out.println("i = " + i);
   }
}
3. JSP表达式(expression)
  • 表达式语法,具有输出功能,输出到浏览器上

表达式的语法格式:

<%= 表达式 %>
  • <%= %> 等同于 out.print();
  • <%=“Hello World!”%> 等同于 out.print(“Hello World!”);
  • <%=1+1%> 等同于 out.print(1+1);
  • <%=“1+1”%> 等同于 out.print(“1+1”);
  • <%= %>中的代码不能以“;”结尾,否则就 out.print(xxx;);显然是没有这种语法的。

五、JSP指令(directive)

  • JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。
  • 为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分

指令语法格式:

<%@ 指令名 属性名=属性值 属性名=属性值.....  %>

JSP中的三种指令标签:

指令描述
<%@ page … %>定义网页依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include … %>包含其他文件
<%@ taglib … %>引入标签库的定义
1.Page指令(页面指令)
  • Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。

Page指令的语法格式:

<%@ page attribute="value" %>
  • importl 属性(翻译生成java语言中的import语句)

<%@page import=”java.util.Date,java.util.ArrayList”%>

  • contentType属性(指定JSP页面响应内容类型)

<%@page contentType=”text/html”%>

  • pageEncoding属性(指定JSP页面响应的页面字符编码)

<%@page pageEncoding=”UTF-8”%>

  • session属性(指定当前JSP页面是否可以使用session这个内置对象)

<%@page session=”false”%> session内置对象不可用
<%@page session=”true”%> session内置对象可用(缺省的

  • errorPage属性(指定当前JSP页面发生错误之后跳转的资源路径)

<%@page contentType=“text/html; charset=UTF-8” errorPage="/error.jsp"%>

  • isErrorPage属性(指定当前JSP页面是一个错误页面,这样才能使用内置对象exception)

<%@page contentType=“text/html; charset=UTF-8” isErrorPage=“true”%>

  • isErrorPage = “false” 表示内置对象exception无法使用【缺省情况下是false】
  • isErrorPage = “true” 表示内置对象exception可以使用
  • isELIgnored属性指定当前页面中如果有EL表达式是否忽略,true表示忽略,false表示不忽略
2. Include指令(包含指令)

Include指令语法格式:

<%@include file="filePath"%>
  • JSP include 指令用于通知 JSP 引擎在翻译当前 JSP 页面时,将其他文件中的内容合并进当前 JSP 页面转换成的 Servlet 源文件中,这种在源文件级别进行引入的方式,称为静态引入
  • 当前 JSP 页面与静态引入的文件紧密结合为一个 Servlet。
  • 因此,在所包含的文件中不能使用 html、body 标记,否则会因为与原有的 JSP 文件有相同标记而产生错误。另外,因为原文件和被包含文件可以相互访问彼此定义的变量和方法,所以要避免变量和方法在命名上产生冲突
  • 这些文件可以是 JSP 页面、HTML 页面、文本文件或是一段 Java 代码。
    • file 属性指定被包含的文件,不支持任何表达式,例如下面是错误的用法:

    <% String f="top.html"; %>
    <%@ include file="<%=f %>" %>

    • 不可以在 file 所指定的文件后接任何参数,如下用法也是错误的:

    <%@ include file="top.jsp?name=zyf" %>

    • 如果 file 属性值以“/”开头,将在当前应用程序的根目录下查找文件;如果是以文件名或文件夹名开头,将在当前页面所在的目录下查找文件。
  • include实现原理:
  1. 编译期包含
  2. a.jsp包含b.jsp,底层共生成一个java源文件,一个class字节码文件,翻译期包含/编译期包含/静态联编
  3. 静态联编的时候,多个jsp中可以共享同一个局部变量,因为最终翻译之后service方法只有一个。
3. Taglib指令(标签库指令)

Taglib指令语法格式:

<%@taglib attribute="value"  %>
  • 为了让JSP看起来更加的专业(只做页面展示),减少jsp页面中java代码的数量,我们引入了标签库,使用了标签库之后JSP程序中不再出现太多的java程序了,这样JSP页面看起来主要工作就是页面展示。

六、JSP动作元素(action)

  • 与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。
  • 利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。

动作语法格式:

<jsp:动作名  属性名=属性值   属性名=属性值....></jsp:动作名>

JSP中几种常用的动作元素:

动作元素描述
jsp:include在页面被请求的时候引入一个文件
jsp:forward把请求转到一个新的页面
jsp:useBean寻找或者实例化一个JavaBean
jsp:setProperty设置JavaBean的属性
jsp:getProperty输出某个JavaBean的属性
1. JSP include动作元素

include动作元素语法格式

<jsp:include page="relative URL"></jsp:include>
  • include 动作用于把另外一个文件的输出内容插入当前 JSP 页面的输出内容中,这种在 JSP 页面执行时引入的方式称为动态引入,这样,主页面程序与被包含文件是彼此独立的,互不影响。

实例代码:

以下我们定义两个文件a.jsp和b.jsp,代码如下所示:

a.jsp文件代码:

<%@page contentType="text/html; charset=UTF-8"%>
<html>
    <head>
        <title>include动作</title>
    </head>
    <body>
          <jsp:include page="/b.jsp"></jsp:include>
    </body>
</html>

b.jsp代码:

<h1 align="center"><font color="red">hello...</font></h1>
  • JSP include动作实现原理
  1. a.jsp包含b.jsp,底层会分别生成两个java源文件,两个class字节码文件
  2. 编译阶段并没有包含,编译阶段是两个独立的class字节码文件,生成两个Servlet,两个独立的service方法
  3. 使用include动作属于运行阶段包含, 实际上是在运行阶段a中的service方法调用了b中的service方法,达到了包含效果
  4. a.jsp包含b.jsp,若两个jsp文件中有重名的变量,只能使用动态包含。其余都可以使用静态包含。
  5. include动作完成的动态包含,被称为动态联编。
  • jsp:indude动作与前面讲解的 include 指令作用类似,现将它们之间的差异总结如下:
  • 1. 属性不同:
  • include指令通过file属性来指定包含页面,不支持任何表达式
  • jsp:include动作是通过 page 属性来指定被包含页面的,该属性支持 JSP 表达式
  • 2. 处理方式不同:
  • 使用 include 指令包含文件时,被包含文件的内容会原封不动地插入到包含页中使用该指令的位置,然后 JSP 编译器再对这个合成的文件进行翻译,所以最终编译后的文件只有一个。
  • 而使用jsp:include动作包含文件时,只有当该标记被执行时,程序才会将请求转发到(注意是转发,而不是请求重定向)被包含的页面,再将其执行结果输出到浏览器中,然后重新返回到包含页来继续执行后面的代码。因为服务器执行的是两个文件,所以 JSP 编器将对这两个文件分别进行编译。
  • 3. 包含方式不同:
  • include 指令的包含过程为静态包含,因为在使用 include 指令包含文件时,服务器最终执行的是将两个文件合成后由 JSP 编译器编译成的一个 Class 文件,所以被包含文件的内容应是固定不变的,若改变了被包含的文件,则主文件的代码就发生了改变,因此服务器会重新编译主文件。
  • jsp:include动作的包含过程为动态包含,通常用来包含那些经常需要改动的文件。因为服务器执行的是两个文件,被包含文件的改动不会影响主文件,因此服务器不会对主文件重新编译,而只须重新编译被包含的文件即可。并且对被包含文件的编译是在执行时才进行的,也就是说,只有当jsp:include动作被执行时,使用该标记包含的目标文件才会被编译,否则,被包含的文件不会被编译。
2. JSP forward 动作元素

forward 动作元素语法格式

<jsp:forward page="Relative URL" />
  • jsp:forward动作把请求转到另外的页面,jsp:forward标记只有一个属性page。
  • 当动作标记被执行后,当前的页面将不再被执行,而是去执行该标记指定的目标页面,但是,用户此时在地址栏中看到的仍然是当前网页的地址,而内容却已经是转向的目标页面了。
  • forward 动作实现的是请求的转发操作,而不是请求重定向。
<jsp:forward page="/index2.jsp" />
//等同于
request.getRequestDispatcher("/index2.jsp").forward(request,response);

它们之间的一个区别就是:

  • 进行请求转发时,存储在 request 对象中的信息会被保留并被带到目标页面中;
  • 而请求重定向是重新生成一个 request 请求,然后将该请求重定向到指定的 URL,所以,事先储存在 request 对象中的信息都不存在了。

实例代码:

  • 创建主页面index.jsp,通过表单输入用户名和密码,单击“登录”按钮,利用 jsp:forward 动作标记跳转到页面 target.jsp。具体代码如下:
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<body>
<form action=" " method="post" name="Form"> <!--提交给本页处理-->
用户名:<input name="UserName" type="text" /> <br/>&nbsp;&nbsp;:<input name="UserPwd" type="text" /> <br/>
<input type="submit" value="登录" />
</form>
<%
    //当单击“登录”按钮时,调用Form1.submit()方法提交表单至本文件,
    //用户名和密码均不为空时,跳转到targe.jsp,并且把用户名和密码以参数形式传递
    String s1=null,s2=null;
    s1=request.getParameter("UserName");
    s2=request.getParameter("UserPwd");
    if(s1!=null && s2!=null)
    {
%>
<jsp:forward page="target.jsp" >
<jsp:param name="Name" value="<%=s1%>" />
<jsp:param name="Pwd" value="<%=s2%>" />
</jsp:forward >
<%
    }
%>
</body>
</html>
  • 创建所转向的目标文件target.jsp,具体代码如下:
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<body>
<%
String strName=request.getParameter("Name");
String strPwd=request.getParameter("Pwd");
out.println(strName+"您好,您的密码是:"+strPwd);
%>
</body>
</html>
3. JSP useBean动作元素
  • jsp:useBean动作标记用于在 JSP 页面中创建 bean 实例,并且通过设置相关属性,可以将该实例存储到指定的范围。如果在指定的范围已经存在该 bean 实例,那么将使用这个实例,而不会重新创建。

useBean动作元素语法格式:

<jsp:useBean id="变量名" class="package.className" scope="page|request|session|application"...></jsp:useBean>
  • 如果多个页面中共享这个 bean 实例,可将 scope 属性设置为 session

七、JSP九大内置对象

  • JSP内置对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP内置对象也被称为预定义变量。

JSP所支持的九大内置对象:

内置对象描述
requestHttpServletRequest类的实例
responseHttpServletResponse类的实例
outPrintWriter类的实例,用于把结果输出至网页上
sessionHttpSession类的实例
applicationServletContext类的实例,与应用上下文有关
configServletConfig类的实例
pageContextPageContext类的实例,代表页面上下文,提供对JSP页面所有对象以及命名空间的访问
page类似于Java类中的this关键字
ExceptionException类的对象,代表发生错误的JSP页面中对应的异常对象
1. request对象
  • 每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。
  • 客户端可通过 HTML 表单或在网页地址后面提供参数的方法提交数据,然后通过 request 对象的相关方法来获取这些数据。
  • request 对象封装了客户端的请求信息,包括用户提交的信息以及客户端的一些信息,服务端通过 request 对象可以了解到客户端的需求,然后做出响应。

request对象常用方法:

方法描述
Object getAttribute(String name)用于返回由 name 指定的属性值,如果指定的属性值不存在,则返回一个 null 值
void setAttribute(String key,Object obj)设置属性的属性值
Enumeration getAttributeNames()用于返回 request 对象的所有属性的名称集合
String getParameter(String name)用于获取客户端传送给服务器端的参数。主要由 name 指定,通常是表单中的参数
Enumeration getParameterNames()用于获取客户端传送的所有参数的名字集合
String getParameterValues(String name)用于获得指定参数的所有值,由 name 指定
String setCharacterEncoding()用于设置请求正文中所使用的字符编码
String getMethod()用于获得客户端向服务器端传送数据的参数方法,主要有两个,分别是 get() 和 post()
cookie[] get Cookie()用于获取所有的 Cookie 对象
  • 获取用户信息

实例代码:

<%@ page contentType="text/html;charset=utf-8" %>
<html>
   <head>
	<title>
    		request对象获取客户信息
	</title>
   </head>
   <body>
	客户提交信息的方式:<%=request.getMethod() %> <br/>
	使用的协议:<%=request.getProtocol() %> <br/>
	获取提交数据的客户端IP地址:<%=request.getRemoteAddr() %> <br/>
	获取服务器端的名称:<%=request.getServerName() %> <br/>
	获取服务器端口号:<%=request.getServerPort() %> <br/>
	获取客户端的机器名称:<%=request.getRemoteHost() %> <br/>
   </body>
</html>
  • 获取请求参数

  • 用户借助表单向服务器提交数据,完成用户与网站之间的交互,表单中包含文本框、列表、按钮等输入标记。当用户在表单中输入信息后,单击 提交 按钮提交给服务器处理。

  • 用户提交的表单数据存放在 request 对象里,通常在 JSP 代码中用 getParameter() 或者 getParameterValues() 方法来获取表单传送过来的数据,前者用于获取单值,如文本框、按钮等;后者用于获取数组,如复选框或者多选列表项。使用格式如下:

String getParameter(String name);
String[] getParameterValues(String name);

以上两种方法的参数 name 与 HTML 标记的 name 属性对应,如果不存在,则返回 null。

  • 修改字符编码
  • 利用 request 的方法获取表单数据时,默认情况下,字符编码为 ISO-8859-1,所以,当获取客户提交的汉字字符时,会出现乱码问题,必须进行特殊处理。

在超链接中传递中文参数:

<a href="目标地址?参数名1=<%=URLEncoder.encode("中文值1")&参数名2=2
 %>>请求参数的值</a>

通过表单或< jsp:param/> 传递中文参数:

<jsp:include page="index.jsp">
	<jsp:param name="num1" value="张三"/>
</jsp:include>

处理乱码问题:

<%
request.setCharacterEncoding("GBK");    //设置编码格式为中文编码,或者utf-8
%>
<%=new String(request.getParameter("name").getBytes("iso-8859-1"),"UTF-8") %>
  • 在作用域中管理属性
  • 通过setAttribute()方法可以在resquest对象的属性列表中添加一个属性,然后在request对象的作用域范围内通过getAttribute()方法将其取出,此外还可以使用removeAttribute()方法将一个属性删除。

设置转发数据的格式:

request.setAttribute("key",value);

获取转发数据的格式:

request.getAttribute("key");
  • 在页面使用 request 对象的 setAttribute(“key”,value) 方法,可以把数据 value 设定在 request 范围内。请求转发后的页面使用 getAttribute(“key”) 就可以取得数据 value。
  • 这一对方法在不同的请求之间传递数据,而且从上一个请求到下一个请求必须是转发请求(使用<jsp: forward >动作来实现),即保存的属性在 request 属性范围(request scope)内,而不能是重定向请求(使用 response.sendRedirect() 或者超级链接来实现)

实例代码:

<!--a.jsp-->
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<head>
<title>
	request对象在作用域中管理属性
</title>
</head>
<body>
	<% request.setAttribute("str","欢迎学习request对象的使用方法!"); %>
	<jsp:forward page="b.jsp"/>
</body>
</html>
<!--b.jsp-->
<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head>
<title>
    request对象在作用域中管理属性
</title>
</head>
<body>
	<% out.println("页面转发后获取的属性值:"+request.getAttribute("str")); %>
</body>
</html>

运行结果图如下:
在这里插入图片描述

在 a.jsp 中,若将语句<jsp:forward page=“b.jsp”/>改成response.sendRedirect(“b.jsp”)或者 《a href=“b.jsp”》 跳转《/a》,就不能获得 request 范围内的属性值。

  • 获取Cookie
  • cookie是小段的文本信息,通过使用cookie可以标识用户身份、记录用户名及密码、跟踪重复用户。
  • cookie在服务器端生成并发送给浏览器,浏览器将cookie的key/value保存到某个指定的目录中,服务器的名称与值可以由服务器端定义。
  1. 通过 request 对象的 getCookies() 方法获取 Cookie 对象的集合,获取 Cookie 的方法如下:
Cookie[] cookie=request.getCookies();
  1. 通过cookie对象的getName()方法可获取指定名称的cookie。
String names = cookies[i].getName()
  1. 通过getValue()方法可获取cookie对象的值。
  2. 通过 response 对象的 addCookie() 方法添加一个 Cookie 对象。添加 Cookie 的方法如下:
String value = response.addCookie(Cookie cookie)
2. response对象
  • response 对象和 request 对象相对应,用于响应客户请求,主要是将JSP容器处理过的对象传回到客户端。response对象只在JSP页面内有效。

response对象常用方法:

方法描述
void addCookie(Cookie cookie)添加一个Cookie对象,用来保存客户端用户信息
void sendError(int xc[,String msg])向客户端发送错误信息
void sengRedirect(java.lang.String location)重定向网页
void set BufferSize(int size)设置缓冲区大小:respones.setBufferSize(0);(不缓冲)
void setCotentType(String type)设置响应的 MIME 类型
void setHeader(String name,String value)设置指定的HTTP文件的值,如果该值已经存在,则新值会覆盖原有的旧值. respones.setHeader(“refresh”,“5”);设置网页每5秒自动刷新一次。
  • 设置页面自动刷新以及定时跳转
  1. 实现页面一秒钟刷新一次,设置语句如下:
response.setHeader("refresh","1");
  1. 实现页面定时跳转,如 2 秒钟后自动跳转到URL所指的页面,设置语句如下:
response.setHeader("refresh","2:URL=页面名称");

实例代码:实现秒表功能

<%@ page contentType="text/html;charset=utf-8" %>
<%@ page contentType="text/html;charset=utf-8" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>
    response 对象设置页面自动刷新
</title>
</head>
<body>
	 <h2> response 对象设置页面自动刷新</h2>
	 <font size="5" color=blue> 数字时钟> </font> <br> <br>
	 <font size="3" color=blue> 现在时刻:<br>
	 <%
	  response.setHeader("refresh","1");
	  int y,m,d,h,mm,s;
	  Calendar c=Calendar.getInstance();
	  y=c.get(Calendar.YEAR);    //年
	  m=c.get(Calendar.MONTH)+1;    //月
	  d=c.get(Calendar.DAY_OF_MONTH);    //日
	  h=c.get(Calendar.HOUR);    //时(HOUR:十二小时制:HOUR_OF_DAY:十二四小时制)
	  mm=c.get(Calendar.MINUTE);    //分
	  s=c.get(Calendar.SECOND);    //分
	  out.println(y+"年"+m+"月"+d+"日"+h+"时"+mm+"分"+s+"秒");
	 %>
	 </font>
</body>
</html>

运行结果图如下:
在这里插入图片描述

3. session对象
  • 客户与服务器之间的通信是通过 HTTP 协议完成的。HTTP 是一种无状态的协议,当客户向服务器发出请求,服务器接收请求并返回响应后,该连接就被关闭了。此时,服务器端不保留连接的有关信息,要想记住客户的连接信息,可以使用 JSP 提供的 session 对象。
  • 用户登录网站时,系统将为其生成一个独一无二的 session 对象,用以记录该用户的个人信息。一旦用户退出网站,那么,所对应的 session 对象将被注销。session 对象可以绑定若干个用户信息或者 JSP 对象,不同的 session 对象的同名变量是不会相互干扰的。
  • 当用户首次访问服务器上的一个 JSP 页面时,JSP 引擎便产生一个 session 对象,同时分配一个 String 类型的 ID 号,JSP 引擎同时将这个 ID 号发送到客户端,存放在 Cookie 中,这样,session 对象和客户端之间就建立了一一对应的关系。
  • 当用户再次访问该服务器的其他页面时,不再分配给用户新的 session 对象,直到用户关闭浏览器,或者在一定时间(系统默认在 30 分钟内,但可在编写程序时,修改这个时间限定值或者显式地结束一个会话)客户端不向服务器发出应答请求,服务器端就会取消该用户的 session 对象,与用户的会话对应关系消失。当用户重新打开浏览器,再次连接到该服务器时,服务器为该用户再创建一个新的 session 对象。

session对象的常用方法:

方法描述
Object getAttribute(String name)获取指定名字的属性
Enumeration getAttributeName()获取 session 中全部属性的名字,一个枚举
public String getld()返回创建 session 时 JSP 引擎为它设置的唯一 ID 号
void invalidate()销毁 session 对象
void removeAttxibute(String name)删除指定名字的属性
void setAttribute(String name,String value)设定指定名字的属性值

创建session对象:

   <%
   	String name = request.getParameter("name"); //获取用户填写的用户名
   	session.setAttribute("name",name); //将用户名保存在session对象中
   %>

获取session对象:

 <%
	String name = (String)session.getAttribute("name"); 
	//获取保存在session范围内的对象
 %>
4. application对象
  • application 对象用于保存应用程序的公用数据,服务器启动并自动创建 application 对象后,只要没有关闭服务器,application 对象就一直存在,所有用户共享 application 对象。

application对象的常用方法:

方法描述
getAttribute( String arg)获取 application 对象中含有关键字的对象
getAttributeNames()获取 application 对象的所有参数名字
setAttribute(String key,Object obj)将参数 Object 指定的对象 obj 添加到 application 对象中,并为添加的对象指定一个索引关键字
removeAttribute(java.lang.String name)根据名字删除 application 对象的参数

实例代码:application对象实现网页计数器

<%@ page import="java.lang.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>计数器</title>
    </head>
    <body>
        <h2>application 对象实现网页计数器</h2>
        <%
            out.println("设置数值");
            Integer intcount;
            if (application.getAttribute("count")==null) {
                intcount=1;
            }else {
                intcount=(Integer.valueOf(application.getAttribute("count").toString()));
            }
            application.setAttribute("name","张三");
            application.setAttribute("count",intcount);
            out.print("set name=张三");
            out.print("<br>set count="+intcount+"<br>");
        %>
    <a href="gateppatter.jsp">计数器页面</a>
    </body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>gateppatter</title>
    </head>
    <body>
        <br>获取用户名:<%=application.getAttribute("name")%>
        <br>计数器
        <%
            int mycount=Integer.valueOf(application.getAttribute("count").toString()).intValue();
            out.println(mycount);
            application.setAttribute("count",Integer.toString(mycount+1));
        %>
    </body>
</html>

运行结果图如下:
在这里插入图片描述
在这里插入图片描述

5.out对象
  • out 对象是一个输出流,用来向客户端输出数据,可以是各种数据类型的内容。同时,它还可以管理应用服务器上的输出缓冲区,缓冲区的默认值是 8KB,可以通过页面指令 page 来改变默认大小。

out对象的常用方法:

方法描述
void print(各种数据类型)将指定类型的数据输出到 HTTP 流,不换行
void println(各种数据类型)将指定类型的数据输出到 HTTP 流,并输出一个换行符
void newline输出换行字符
6. pageContext对象
  • pageContext 是页面上下文对象。
  • 它可以访问本页所有的 session,也可以取本页所在的 application 的某一属性值,它相当于页面中所有其他对象功能的集大成者,可以用它访问本页中所有的其他对象。
  • pageContext 对象的主要作用是提供一个单一界面,以管理各种公开对象(如 session、application、config、request、response 等),提供一个单一的 API 来管理对象和属性。
  • pageContext只能在同一个JSP页面中共享数据。可以获取include指令包含的jsp页面中存储的数据,但是不能获取include动作包含的jsp页面中存储的数据。范围是最小的。

pageContext 对象在实际 JSP 开发过程中很少使用,因为 request 和 response 等对象可以直接调用方法进行使用

7. config对象
  • config 对象是 javax.servlet.ServletConfig 类的实例,表示 Servlet 的配置信息。
  • 当一个 Servlet 初始化时,容器把某些信息通过此对象传递给这个 Servlet,这些信息包括 Servlet 初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个 ServletContext 对象),config 对象的应用范围是本页。
  • 开发者可以在 web.xml 文件中为应用程序环境中的 Servlet 程序和 JSP 页面提供初始化参数。
8. page对象
  • 这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。
  • page 对象是为了执行当前页面应答请求而设置的 Servlet 类的实体,即显示 JSP 页面自身,与类的 this 指针类似,使用它来调用 Servlet 类中所定义的方法,只有在本页面内才是合法的。

page对象的常用方法:

方法描述
class getClass()返回当前 Object 的类
int hashCode返回 Object 的 hash 代码
String toString把 Object 对象转换成 String 类的对象
boolean equals(Object obj)比较对象和指定的对象是否相等
9. exception 对象
  • exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。
对比JSP中的四个作用域对象

范围比较:pageContext < request < session < application

  • pageContext : 在同一个JSP页面中共享数据,不能跨JSP页面
  • request : 在同一个请求中共享数据 【使用较多】
  • session : 在同一个会话中共享数据 【使用较多】
  • application : 所有用户共享的数据可以放到应用范围中
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@烟雨倾城ゝ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值