Java Web(十二)--JSP

JSP

介绍

JSP的全称是Java Server Pages,是为了简化Servlet的工作而出现的动态网页开发技术。

它在HTML代码中嵌入Java代码片段和JSP标签,构成以.jsp结尾的文件。其中,HTML代码用于显示静态内容,Java代码片段用于显示动态内容,这就避免直接使用Servlet逐句响应HTML页面的烦琐,同时降低了代码冗余。

jsp 技术基于 Servlet, 你可以理解成 JSP 就是对 Servlet 的包装。

  • Servlet是JavaEE的13个子规范之一,那么JSP也是JavaEE的13个子规范之一。
  • JSP是一套规范。所有的web容器/web服务器都是遵循这套规范的,都是按照这套规范进行的"翻译"。每一个web容器/web服务器都会内置一个JSP翻译引擎。
  • JSP 是 Servlet 的扩展,我们可以在 JSP 中使用 Servlet 的所有功能。另外,使用 JSP 标签可在 HTML 网页中插入 Java 代码,标签通常以<%开头,以%>结束;包括 Java Bean、自定义标签(Custom Tags)、EL 表达式(Expression Language)、JSTL 标准标签类库(Java Standard Tag Library)等。
  • JSP 依赖于 Servlet,用户访问 JSP 页面时,JSP 代码会被翻译成 Servlet 代码,最终,以字符串的形式向外输出 HTML 代码。

JSP 与 PHP、ASP、ASP.NET 等语言类似,都运行在服务端;

jsp 页面不能像 HTML 页面, 直接用浏览器运行;只能通过浏览器访问 Tomcat 来访问。

优点

  • 与纯 Servlets相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句。
  • 与JavaScript相比:虽然JavaScript可以在客户端动态生成HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等。
  • 与静态HTML相比:静态HTML不包含动态信息。

JSP本质

JSP页面本质上是一个Servlet程序。

比如现在我们来写第一个jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
      第一个jsp
  </body>
</html>

项目部署完成后,访问index.jsp

  • 实际上访问以上的这个:index.jsp,底层执行的是:index_jsp.class 这个java程序。
  • 这个index.jsp会被tomcat翻译生成index_jsp.java文件,然后tomcat服务器又会将index_jsp.java编译生成index_jsp.class文件
  • 访问index.jsp,实际上执行的是index_jsp.class中的方法。

打开编译后对应的字节码文件:

且这个类继承有HttpJspBase。

因此说JSP实际上就是一个Servlet。

  • index.jsp访问的时候,会自动翻译生成index_jsp.java,会自动编译生成index_jsp.class,那么index_jsp这就是一个类。
  • index_jsp 类继承 HttpJspBase,而HttpJspBase类继承的是HttpServlet。所以index_jsp类就是一个Servlet类。
  • jsp的生命周期和Servlet的生命周期完全相同。完全就是一个东西。

注意:对JSP进行错误调试的时候,还是要直接打开JSP文件对应的java文件,检查java代码。
out对象说明:

out对象的类型是javax.servlet.jsp.JspWriter。他的作用与ServletResponse.getWriter()所返回的PrintWriter对象非常相似,功能都是用来向客户端发送文本形式的响应。不同的是out对象类型是JspWriter,是一种带缓存的PrintWriter。

out对象通过write()方法写入数据后,一直要等到整个JSP页面结束,out对象中缓冲区的数据才会真正写入servlet引擎提供的缓冲区中.

PrintWriter对象的write()方法是直接把数据写入servlet引擎的缓冲区中.Servlet引擎按照缓冲区中的数据存放顺序,向页面输出内容。


JSP的生命周期

【1】编译阶段:

servlet容器编译servlet源文件,生成servlet类

【2】初始化阶段:

加载与JSP对应的servlet类,创建实例,并调用它的初始化方法

【3】执行阶段:

调用与JSP对应的servlet实例的服务方法

【4】销毁阶段:

调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例。

JSP生命周期的四个主要阶段和servlet生命周期非常相似 ,但是也有不同的地方。

  • jsp文件第一次访问的时候是比较慢的
    • 第一次访问的时候比较麻烦:
    • 要把jsp文件翻译生成java源文件
    • java源文件要编译生成class字节码文件
    • 然后通过class去创建servlet对象
    • 然后调用servlet对象的init方法
    • 最后调用servlet对象的service方法。
  • 之后就比较快了
    • 因为以后直接调用单例servlet对象的service方法即可。

JSP指令标签

作用:

  1. 用于指示JSP执行的某些步骤;
  2. 用于指示JSP变现特定行为;

语法:<%@ 指令名称 属性名称=属性的值 属性名称=属性的值 %>

|------------------|-------------------------------|
| 指令 | 描述 |
| <%@ page %> | 定义网页依赖属性,如脚本语言、error页面、缓存需求等等 |
| <%@ include %> | 包含其他文件 |
| <%@ taglib %> | 引入标签库的定义 |

(1)page指令标签

JSP头部的Page指令。

作用:Page指令可以修改整个页面的属性和行为。

Page指令中属性说明:

  • (1) contentType属性:用于指定MIME消息类型和JSP响应时所采用的字符编码方式。即表示JSP返回的数据类型是什么,即response.setContentType()的参数值。【一般为"text=html;charset="utf8"】
  • (2) language属性:表示JSP翻译之后是什么语言文件(目前只支持Java)
  • (3) pageEncoding属性:表示当前JSP文件本身的字符集(可在IDEA右下角看到)
  • (4) import属性:通过该属性引用脚本中使用到的类文件;即表示导包(导类),与Java一致
  • (5) autoFlush属性:设置当out输出流缓冲区满了之后是否自动刷新缓冲区,默认值是true
  • (6) buffer属性:设置out缓冲区的大小,默认是8kb
  • (7) errorPage属性:设置当JSP页面运行出错时自动跳转到的页面(错误信息页面)的路径,这个 路径一般都是以斜杠打头,表示请求的地址是http://ip:port/工程路径/,对应代码web目录
  • (8) isErrorPage属性:设置当前JSP页面是否是错误信息页面,默认是false,如果是true可以 获取错误信息。
  • (9) session属性:设置访问当前JSP页面时是否会创建HttpSession对象,默认值是true
  • (10) extends属性:设置JSP页面翻译出来的Java类默认继承谁

注意:

out缓冲区满了之后不能自动刷新的话会报错

以上默认值除非有特殊需要,否则不建议修改

(2)include指令标签

JSP可以通过include指令来包含其他文件。被包含的文件可以是jsp文件、HTML文件或文本文件。

包含的文件就像是jsp文件的一部分,会被同时编译执行。

除了使用include指令标签可以实现引入外,使用jsp:include动作也可以实现引入。

  • 静态引入: @include 被引入的网页和当前页生成代码后形成了一个java文件
  • 动态引入: jsp:include 被引入的JSP页面会生成独立的java代码

<%--

静态引入,被引入的jsp页面不会单独生成java代码文件,

当前页和被引入页会生成一个java文件

--%>

<%@ include file="hello2.jsp"%>

<%--

动态引入:被引入的页面会生成独立的java代码,在当前页生成的java代码中使用

引入其他页面

--%>

<jsp:include page="hello3.jsp"></jsp:include>

(3)taglib指令标签

taglib就是标签库的意思,我们可以在jsp页面中引入其他的标签库,帮我们去快速简单的做一些事情。

<%@ taglib uri="uri" prefix="prefixOfTag" %>

属性

  • uri属性: 引入的标签库的路径
  • prefix属性: 引入标签库的别名

JSP脚本

在 JSP 中,可以使用 JSP 脚本写入 Java 代码;JSP 脚本可以包含任意数量的 Java 语句,变量、方法和表达式;JSP 脚本会把包含的内容插入到 Servlet 的 service() 方法中。

【1】JSP声明语句

  • 声明脚本的格式是: <%! 声明 java 代码 %>
  • 作用:定义 jsp 的需要属性、方法、静态代码块和内部类等
  • 特点:
    • 不会在浏览器的页面上显示出来,仅存在于翻译后的Java类中;

    • 不建议使用,可能存在线程安全问题。

      <%--
      Created by IntelliJ IDEA.
      --%>

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

      <html> <head> <title>jsp声明脚本</title> </head> <body>

      jsp声明脚本

      <%!
      //这里我们可以声明该jsp需要使用的属性,方法,静态代码块, 内部类
      //也就是给 statement.jsp 对应的 statement_jsp 类定义成员

      //1. 属性
      private String name = "jack";
      private int age;
      private static String company;
      
      //2 方法
      public String getName() {
          return name;
      }
      
      //3. 静态代码块
      static {
          company = "字节跳动";
      }
      

      %>

      </body> </html>

【2】表达式脚本

  • 格式:<%=表达式%>
  • 作用:在jsp 页面上输出数据(只有此脚本可以在浏览器的页面上输出数据);可以把变量或者表达式输出到网页上,不需要 out.print() 就能输出数据;通常用于打印变量和方法的值。
  • 特点:
    • (1) 所有的表达式脚本都会被翻译到对应的Java类的_jspService()方法中,故表达式脚本可以 直接使用_jspService()方法参数中的对象;

    • (2) 表达式脚本都会被编译后的Java类中的out.print()方法输出到浏览器页面上;

    • (3) 表达式脚本中的表达式不能以分号结束。

      <%--
      Created by IntelliJ IDEA.
      --%>

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

      <html> <head> <title>表达式脚本的使用</title> </head> <body>

      个人信息

      <% String name = "老师"; String email = request.getParameter("email"); %> 用户名: <%=name%>
      工作是: <%="java工程师"%>
      年龄: <%=request.getParameter("age")%>
      电邮: <%=email%> </body> </html>

注意:

1.write方法中的标签、转义字符自动识别为对应的功能,不在页面输出,执行各自代表的功能。

2.out的两个方法也在_jspService方法中,也都是java语言。

3.只有print、write方法、表达式脚本中的内容才可在浏览器中显示,其余Java代码的out在控制台输出。


【3】代码脚本

  • 语法: <% Java语句 %>
    • 任何文本、HTML 标签和 JSP 元素(声明,表达式等)都必须在脚本程序之外;
  • 作用:可以在 jsp 页面中,编写我们需要的功能(使用 java )
    • 代码脚本翻译后都在_jspService方法中,故代码脚本可以直接使用此方法参数中的对象;

    • 可以由多个代码脚本块组合完成一个完整的 java 语句

    • 代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据。

      <%@ page import="java.util.ArrayList" %>
      <%@ page import="com.hspedu.entity.Monster" %>
      <%--
      Created by IntelliJ IDEA.
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>

      <html> <head> <title>演示代码脚本</title> </head> <body>

      演示代码脚本

      <%
      //创建ArrayList ,放入两个monster对象
      ArrayList<Monster> monsterList = new ArrayList<>();
      monsterList.add(new Monster(1, "牛魔王", "芭蕉扇"));
      monsterList.add(new Monster(2, "蜘蛛精", "吐口水"));
      %>

      <% for (int i = 0; i < monsterList.size(); i++) { //先取出monster对象 Monster monster = monsterList.get(i); %>
      <tr>
          <td><%=monster.getId()%>
          </td>
          <td><%=monster.getName()%>
          </td>
          <td><%=monster.getSkill()%>
          </td>
      </tr>
      <%
          }
      %>
      
      id 名字 技能
      </body> </html>

JSP的注释

1.HTML注释:<!--HTML注释-->

  • HTML注释会被翻译到JSP文件对应的Java类的_jspService方法中,以out.write()输出到客户端;
  • write方法会自动识别标签,执行标签对应的功能,不会在浏览器的页面上输出注释。

2.Java注释:(1) //单行注释 (2) /*多行注释*/

  • Java注释要写在声明脚本和代码脚本中才被认为是Java注释,会被翻译到JSP文件对应的Java类的_jspService方法中,在对应的Java类中也是注释。

3.JSP注释:<%- -这是JSP注释- -%>

  • JSP注释中的内容不会在JSP文件翻译后的Java类中出现,即注释中的内容没有任何功能。

JSP 内置对象

JSP 中一共预先定义了 9 个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception。

1、request对象

request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信

息,主要⽤于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求⽅式以及请求参数等)。request对象的作⽤域为⼀次请求。

2、response对象

response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作⽤域,它只在JSP⻚⾯内有效。所属类型:HttpServletResponse

3、session对象

session 对象是由服务器⾃动创建的与⽤户请求相关的对象。服务器为每个⽤户都⽣成⼀个session对象,⽤于保存该⽤户的信息,跟踪⽤户的操作状态。session对象内部使⽤Map类来保存数据,因此保存数据的格式为 "Key/value"。 session对象的value可以使复杂的对象类型,⽽不仅仅局限于字符串类型。

4、application对象

application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应⽤中都有效。与session对象相⽐,application对象⽣命周期更⻓,类似于系统的"全局变量"ServletContext。

区别:

  • request:单次请求
  • session:浏览器访问期间(会话期间)
  • application:服务器启动期间,所存的数据可以跨浏览器

5、out 对象

out 对象⽤于在Web浏览器内输出信息,并且管理应⽤服务器上的输出缓冲区。在使⽤ out 对象输出数据时,可以对数据缓冲区进⾏操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。

示例:

6、pageContext 对象

pageContext 对象的作⽤是取得任何范围的参数,通过它可以获取 JSP⻚⾯的out、equest、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP⻚⾯中可以直接使⽤ pageContext对象。

7、config 对象

config 对象的主要作⽤是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() ⽅法可以获取⼀个config对象。当⼀个Servlet 初始化时,容器把某些信息通过config对象传递给这个Servlet。 开发者可以在web.xml ⽂件中为应⽤程序环境中的Servlet程序和JSP⻚⾯提供初始化参数。

8、page 对象

page 对象代表JSP本身,只有在JSP⻚⾯内才是合法的。 page隐含对象本质上包含当前 Servlet接⼝引⽤的变量,类似于Java编程中的 this 指针。

9、exception 对象

exception 对象的作⽤是显示异常信息,只有在包含 isErrorPage="true" 的⻚⾯中才可以被使⽤,在⼀般的JSP⻚⾯中使⽤该对象将⽆法编译JSP⽂件。

excepation对象和Java的所有对象⼀样,都具有系统提供的继承结构。exception 对象⼏乎定义了所有异常情况。在Java程序中,可以使⽤try/catch关键字来处理异常情况; 如果在JSP⻚⾯中出现没有捕获到的异常,就会⽣成 exception 对象,并把exception 对象传送到在page指令中设定的错误⻚⾯中,然后在错误⻚⾯中处理相应的 exception 对象。

(1)先在可能发⽣错误的⻚⾯中添加errorPage属性:

(2) 在error.jsp⻚⾯中设置isErrorPage="true" 的属性(使⽤exception对象之前,需要先将当前⻚⾯设置成错误⻚⾯)


JSP四大作用域对象

说明:

  • 1)在上述九大内置对象中,有四大域对象,分别是:pageContext(PageContextImpl类)、request(HttpServlerRequest类)、session(HttpSession类)、application(ServletContext类)
  • 2)域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样,不同的是它们对数据的存取范围。
  • 3)四大域对象存取范围:分别给四个对象存入数据,并取出

分类:

  • pageContext(PageContextImpl类) --- 当前 jsp 页面范围内有效,开发时使用较少。
  • request(HttpServlerRequest类) --- 一次请求(转发)内有效,使用非常多。
  • session(HttpSession类) --- 一次会话范围内有效(浏览器访问服务器,直到浏览器关闭,数据都在),使用的比较多。
  • application(ServletContext类) --- 整个 web 工程范围内都有效(只要web不停止,数据都在),因为范围太大,应尽量少用。

四大域对象存入数据,并取出:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>四大域对象</title>
</head>
<body>
    <h1>四大域对象</h1>
    <%
        //给四大域对象存入数据
        pageContext.setAttribute("pageContextKey","pageContextValue");
        request.setAttribute("requestKey","requestValue");
        session.setAttribute("sessionKey","sessionValue");
        application.setAttribute("applicationKey","applicationValue");
    %>
    pageContext域中是否有值:
    <%=
        // 取出四大域对象中的值
        pageContext.getAttribute("pageContextKey")
    %><br>
    request域中是否有值:
    <%=
    // 取出四大域对象中的值
            request.getAttribute("requestKey")
    %><br>
    session域中是否有值:
    <%=
    // 取出四大域对象中的值
            session.getAttribute("sessionKey")
    %><br>
    application域中是否有值:
    <%=
    // 取出四大域对象中的值
            application.getAttribute("applicationKey")
    %><br>
 
    <%
        //一次请求
        request.getRequestDispatcher("/四大域对象范围测试.jsp").forward(request,response);
    %>
</body>
</html>

四大域对象不存入数据,直接取出:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>四大域对象</title>
</head>
<body>
    <h1>四大域对象范围测试</h1>
 
    pageContext域中是否有值:
    <%=
        // 取出四大域对象中的值
        pageContext.getAttribute("pageContextKey")
    %><br>
    request域中是否有值:
    <%=
    // 取出四大域对象中的值
            request.getAttribute("requestKey")
    %><br>
    session域中是否有值:
    <%=
    // 取出四大域对象中的值
            session.getAttribute("sessionKey")
    %><br>
    application域中是否有值:
    <%=
    // 取出四大域对象中的值
            application.getAttribute("applicationKey")
    %><br>
</body>
</html>

4)**四大域对象在使用上的优先顺序:pageContext > request > session > application,**有效范围越小,若数据不使用,就会在越短的时间,数据释放就会越快,从而减轻服务器内存的压力。


JSP的动作标签

是什么?

JSP的动作标签用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写Java代码,造成jsp页面难以维护。

常用的动作标签

<jsp:forward/> :请求转发。

<jsp:include/>:包含(动态包含)。

<jsp:param/>:传递参数。


EL

EL表达式:Expression Language表达式语言。它不是一种开发语言,是jsp中获取数据的一种规范。目的是简化jsp中java代码开发,代替脚本表达式<%=username%>。

格式如: ${EL表达式} 等价于<%=pageContext.findAttribute(name)%>

参考文档:JSP 表达式语言 | 菜鸟教程

注意:使用EL表达式,需要在page指令中启用EL表达式。

  • EL表达式只能读取数据,不能修改数据
  • EL表达式只能处理四大域中的属性值及常量

作用 :

1、获取数据

EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)

2、执行运算

利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}

3、获取web开发常用对象

EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。

4、调用Java方法

EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。

<%@ page import="java.util.*" %>
<%@ page import="com.lxyk.domain.User" %><%--
  Created by IntelliJ IDEA.
  User: EDY
  Date: 2022/4/8
  Time: 21:06
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el表达式</title>
</head>
<body>
      <h3> 作用和意义 </h3>
      <p>1.代替java小脚本的输出格式,简化域中取值</p>
      <p>2.统一规范页面的标签书写规范</p>
 
      <h3> el---expression language表达式语言</h3>
       <p>语法格式---${内置对象.键名}</p>
 
       <h4>el表达式取单值</h4>
      <%
          pageContext.setAttribute("name","pageContext");
          request.setAttribute("name","request");
          session.setAttribute("name","session");
          application.setAttribute("name","application");
      %>
       <p>取域中的单值----${name}--${requestScope.name}--${sessionScope.name}--${applicationScope.name}</p>
 
      <h4>el表达式取数组中的值</h4>
        <%
            int[] arr = {5,3,8,10,20};
            request.setAttribute("array",arr);
        %>
       <p>从数组中取值要结合下标---${requestScope.array[0]}</p>
 
      <h4>el表达式取集合中的值</h4>
        <%
            List list = new ArrayList();
            Collections.addAll(list,"aa","bb","cc");
            request.setAttribute("list",list);
        %>
       <p>从集合中取值要结合下标---${requestScope.list[0]}--${requestScope.list.get(0)}</p>
 
      <h4>el表达式取map集合中的值</h4>
      <%
          Map<String,String> map = new LinkedHashMap<String,String>();
           map.put("a","北京");
           map.put("b","上海");
           map.put("d.a","武汉");
           request.setAttribute("map",map);
      %>
      <p>从map集合中取值--${requestScope.map.a}--${requestScope.map.get("b")}--${requestScope.map['d.a']}</p>
 
      <h4>el表达式取javaBean中的值</h4>
      <%
            User user = new User("张三丰",108,0);
            request.setAttribute("u",user);
      %>
      <p> 从javabean对象中取值----${requestScope.u.name}---${u.toString()}</p>
 
     <hr/>
      <h3>el中的11个内置对象</h3>
 
       <dl>
           <dt>el中支持的4个域对象</dt>
           <dd>pageScope--本页面域</dd>
           <dd>requestScope--请求域</dd>
           <dd>sessionScope--回话域</dd>
           <dd>applicationScope--app域</dd>
       </dl>
       <dl>
           <dt>el中支持的2个头对象+2个参数</dt>
           <dd>header--请求头相关数据</dd>
           <dd>headerValues--请求头值相关数据</dd>
           <dd>param--参数相关数据</dd>
           <dd>paramValues--参数值相关数据</dd>
       </dl>
       <p>头相关数据获取--${header.keySet()}</p>
       <p> 参数相关数据获取--${paramValues.values()}</p>
 
      <dl>
          <dt>el中支持的cookie</dt>
          <dd>cookie--请求头相关cookie数据</dd>
          <dd>${cookie.keySet().toArray()[0]}</dd>
      </dl>
 
      <dl>
          <dt>el中支持的pageContext及initPara</dt>
          <dd>pageContext--本页面上下文</dd>
          <dd>initParm--全局参数</dd>
          <dd>${pageContext.request}</dd>
          <dd>${initParam.keySet()}</dd>
      </dl> 
 
</body>
</html>

隐式对象

EL表达式定义了11个web开发常用对象。使用这些对象可以很方便获取web开发冲的一些常见对象,并可以读取这些对象中的数据。

内置对象 类型 作用
pagecontext pagecontextImpl 获取jsp中的九大内置对象
pagescope map 获取pagecontext域中的数据
requestscope map 获取request域中的数据
sessionscope map 获取session域中的数据
applicationscope map 获取application域中的数据
param map 获取请求参数的值(接收一个名称对应一个值参数)
paramvalues map 获取请求参数的值,获取多个值的时候使用。(接收一个名称对应多个值参数)
header map 获取请求头的信息;(获取一个key对应一个value 头)
headervalues map 获取请求头的信息,可以获取多个值的情况;(获取一个key对应多个value 头)
cookie map 获取当前请求的cookie信息; (${cookie.key.name} ${cookie.key.value})
initParam map 获取在web.xml中配置的上下文参数

EL表达式中的pageContext对象与JSP中的pageContext对象是同一个,都可以获取request、response、session、servletConfig等对象,但request、response、session、servletConfig等对象并不是EL的内置对象,只能通过pageContext获取。

EL表达式获取对象的方法其实是对Java方法的封装,例如**${pageContext.request}获取request对象。** 其底层实际调用的pageContext.getRequest()方法。


JSTL

参考文档:JSP 标准标签库(JSTL) | 菜鸟教程

JSTL:全称Java Server Pages Standard Tag Library,JSP标准标签库,代替jsp页面的脚本,实现逻辑控制。

JSTL的作用:实现JSP页面中逻辑处理。如判断, 循环等;

JSTL由四个定制标记库(core、format、xml 和 sql)和一对通用标记库验证器组成。目前常使用的是他的核心库:

|-----------|----------------------------------------|-------|
| 标签库 | 标签库的URI | 前缀 |
| Core | http://java.sun.com/jsp/jstl/core | c |
| I18N | http://java.sun.com/jsp/jstl/fmt | fmt |
| SQL | http://java.sun.com/jsp/jstl/sql | sql |
| XML | http://java.sun.com/jsp/jstl/xml | x |
| Functions | http://java.sun.com/jsp/jstl/functions | fn |

JSTL是标签,EL是表达式,两者结合JSP页面基本不需要<% %>代码了。


使用

要使用JSTL,首先需要导入其核心包和依赖包.

然后在jsp页面中通过taglib指令,引入标签库. 我们使用最多的就是核心库core。

在JSP中引入标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

目前开发中,最常用的两个标签是<c:if>和<c:foreach>标签。

如果配合EL使用,JSP中一定要加<%@ page isELIgnored="false"%>


常用标签

核心标签有以下几种标记

  • 表达式操作 out、set、remove、catch
  • 流程控制 if、choose、when、otherwise
  • 迭代操作 forEach、forTokens
  • URL操作 import、param、url、redirect

通用标签set,out,remove

<c:set> :主要用来将变量存储至JSP范围中 或是JavaBean的属性或Map对象中;

|----------|----------------|-----------|---------|
| 名称 | 说明 | 是否必须写 | 默认值 |
| value | 要被存储的值 | 否 | 无 |
| var | 存入的变量名称 | 否 | 无 |
| scope | var变量的JSP范围 | 否 | Page |
| target | JavaBean或Map对象 | 否 | 无 |
| property | 指定target对象的属性 | 否 | 无 |

<c:out>主要用来显示数据的内容;

|-----------|-----------------------------|-----------|---------|
| 名称 | 说明 | 是否必须写 | 默认值 |
| value | 需要显示出来的值 | 是 | 无 |
| default | 如果value的值为null,则显示default的值 | 否 | 无 |
| escapeXml | 是否转换特殊字符,如:<转换成 & lt; | 否 | TRUE |

<c:remove> 主要负责移除变量;

|--------|-------------|-----------|---------|
| 名称 | 说明 | 是否必须写 | 默认值 |
| var | 欲移除的变量名称 | 是 | 无 |
| Scope | var变量的jsp范围 | 否 | Page |

<!-- 基础标签:声明变量,输出变量,移除变量,变量默认值 -->
	<h3>基础标签:声明变量,输出变量,移除变量,变量默认值</h3>
<!--1.声明变量k   var:是变量名  value:变量的值(必须是EL表达式)-->
	<c:set var="k" value="${1+1}"></c:set>
<!--2.输出变量k   value:使用EL表示表示变量-->
	移除前输出的内容:<c:out value="${k}"></c:out><br>
<!--3.移除指定变量  -->	
	<c:remove var="k"/>
	移除后输出的内容:<c:out value="${k}"></c:out><br>
<!--4.给指定变量赋默认值  -->
	默认值:<c:out value="${m}" default="123456"></c:out>

<%--向域中设置数据--%>
<c:set var="username" value="张三" ></c:set>
<c:set var="address" value="深圳" ></c:set>
<%--标签内容会被输出,不安全--%>
<%--<c:set var="content" value="<script type='text/javascript'> alert('欢迎使用JSTL')</script>" ></c:set>--%>
${username}
${address}
${content}

<c:out  value="<script type='text/javascript'> alert('欢迎使用JSTL')</script>" ></c:out>
<c:remove  var="content" ></c:remove>

条件标签if,choose

**<c:if> 主要用于进行if判断,如果为true,则输出标签体中的内容。**如果有多种条件,就必须写多个<c:if>标签,因为JSTL中没有给我们提供else标签.。

|--------|------------------------------|-----------|---------|
| 名称 | 说明 | 是否必须写 | 默认值 |
| test | 表达式的结果为true,则执行体内容,false则相反 | 是 | 无 |
| var | 如果 用来存储test运算的结果(true或false) | 否 | 无 |
| scope | Var变量的JSP范围 | 否 | page |

<c:choose >,<c:when >,<c:otherwise > 作用相当于if-else

|--------|-----------------------------|-----------|---------|
| 名称 | 说明 | 是否必须写 | 默认值 |
| test | 表达式的结果为true,则执行体内容,false则相反 | 是 | 无 |

<c:if test="${empty user}">没有登录</c:if>

<h3>条件标签:choose(等价于java中switch)</h3>
<%-- 测试成绩等级 >90 优秀   >80  良好    >70 中等   >60及格--%>
<c:set var="score" value="80"></c:set>
<c:choose>
	<c:when test="${score>=90 }">优秀</c:when>
	<c:when test="${score>=80 }">良好</c:when>
	<c:when test="${score>=70 }">中等</c:when>
	<c:when test="${score>=60 }">及格</c:when>
	<c:otherwise>不及格</c:otherwise>
</c:choose>

迭代标签

<c:forEach> 循环控制,它可以将数组,集合(Collection)中的成员循序浏览一遍。

|-----------|------------------------|--------|---------|
| 名称 | 说明 | 必须 | 默认值 |
| var | 当前迭代对象的信息保存到page域中的名称. | 是 | 无 |
| items | 被迭代的集合对象(需要使用EL表达式) | 否 | 无 |
| varStatus | 当前迭代对象的信息保存到page域中的名称. | 否 | 无 |
| begin | 开始的位置,从0开始。 | 否 | 0 |
| end | 结束的位置 | 否 | 最后一个成员 |
| step | 每次迭代的间隔数 | 否 | 1 |

for基础遍历

<!-- 遍历for:输出1到10 的值 -->
	<!--var: 变量,把遍历的每一个值都存储在变量中进行输出
    begin:开始   如果是变量使用EL表达式表示
    end:结束    如果是变量使用EL表达式表示
    step:间隔的长度
    for( int i=0;i<10;i++){
     System.out.println(i);
    }
     -->
示例代码:
<c:forEach var="i" begin="1" end="10" step="2">
 ${i}<br>
</c:forEach>

foreach遍历

  <h3>测试list集合遍历获取学生列表</h3>
      <table border="1" width="80%" bordercolor="red" cellspacing="0"
          align="center">
          <tr>
              <th>学号</th>
              <th>姓名</th>
              <th>成绩</th>
              <th>班级</th>
              <th>是否是第一个</th>
              <th>是否是最后一个</th>
              <th>计数count</th>
              <th>索引index</th>
          </tr>
   <!-- varStatus:变量状态:遍历出的每一项内容的状态:
      isFirst()      first
      isLast()       last
      getCount()     count  计数  重要的
      getIndex()     index
       -->
       <!-- var :遍历出的每一项使用变量先存储
            items:集合(使用El表达式)
            -->
          <c:forEach var="stu" items="${students}" varStatus="vs">
              <tr>
                  <td>${stu.id}</td>
                  <td>${stu.name}</td>
                  <td>${stu.score}</td>
                  <td>${stu.classes}</td>
                  <td>${vs.first}</td>
                  <td>${vs.last}</td>
                  <td>${vs.count}</td>
                  <td>${vs.index}</td>
              </tr>
          </c:forEach>
   </table>

url标签

<c:url var="" value="">

举例:
 <c:url var="loc" value="/stu.jsp">
        <c:param name="username" value="张三"></c:param>
    </c:url>

 <a href="${loc}">学生列表</a>
相关推荐
blammmp15 分钟前
Java:数据结构-枚举
java·开发语言·数据结构
bysking24 分钟前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
何曾参静谧27 分钟前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵33 分钟前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong38 分钟前
Java反射
java·开发语言·反射
Troc_wangpeng39 分钟前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
王哲晓40 分钟前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
努力的家伙是不讨厌的41 分钟前
解析json导出csv或者直接入库
开发语言·python·json
fg_41143 分钟前
无网络安装ionic和运行
前端·npm
理想不理想v1 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试