Java --- JSP2新特性

     自从03年发布了jsp2.0之后,新增了一些额外的特性,这些特性使得动态网页设计变得更加容易。jsp2.0以后的版本统称jsp2。主要的新增特性有如下几个:

  • 直接配置jsp属性
  • 表达式语言(EL)
  • 标签文件(Tag File)

一、直接配置jsp属性
     原先我们对于jsp页面的一些属性的配置需要使用编译指令page在页面的头部指定,这就会导致在多个jsp页面中都做了同样的事情。jsp2为我们提供了一种方式,可以在web.xml中统一指定某个或者某些jsp页面的一些属性配置。主要的可配置的jsp属性有:

<el-ignored></el-ignored>   ---指定该jsp页面是否支持表达式语言

<page-encoding></page-encoding>     ---指定该jsp页面的编码方式

<scripting-invalid></scripting-invalid>    --指定该页面是否允许jsp脚本

<include-prelude></include-prelude>    --向指定的页面隐式的包含外部文件(引入的位置在指定页面的头部)

<include-coda></include-coda>       --向指定的页面隐式的包含外部文件(引入的位置在指定页面的底部)

在web.xml中我们使用元素jsp-config来直接配置jsp属性,每个jsp-config元素下,可以由多个jsp-property-group元素,它就是用来具体配置某个或者某些jsp属性的,具体看下面的演示:

    <jsp-config>
        <jsp-property-group>
            <url-pattern>/index.jsp</url-pattern>
            <el-ignored>false</el-ignored>
            <page-encoding>UTF-8</page-encoding>
            <scripting-invalid>false</scripting-invalid>
            <include-prelude>/top.jsp</include-prelude>
            <include-coda>/bottom.jsp</include-coda>
        </jsp-property-group>

        <jsp-property-group>
            <url-pattern>/index2.jsp</url-pattern>
            <el-ignored>true</el-ignored>
            <page-encoding>UTF-8</page-encoding>
            <scripting-invalid>true</scripting-invalid>
            <include-prelude>/top.jsp</include-prelude>
            <include-coda>/bottom.jsp</include-coda>
        </jsp-property-group>
    </jsp-config>

其中url-pattern元素用来指定哪些jsp页面将被应用以下配置,可以是单个jsp页面,也可以是一组jsp页面。el-ignored元素指定该页面是否支持表达式语言(接下来会说),默认是false表示支持EL。page-encoding元素指定了页面的编码方式,等效于jsp页面page编译指令中contentType属性中charset部分。scripting-invalid元素指定了页面是否支持jsp脚本,默认为false表示支持。include-prelude和include-coda元素我们分别隐式引用了外部文件,一个放在原页面的头部,另一个则是放在尾部。我们看看这两个页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<html>
  <head>
    <title>top.jsp</title>
  </head>
  <body>
      <p>这是头部的内容</p>
  </body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<html>
  <head>
    <title>bottom.jsp</title>
  </head>
  <body>
      <p>这是底部的内容</p>
  </body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<html>
  <head>
    <title>index.jsp</title>
  </head>
  <body>
      <p>这是index页面的内容</p>
      <p>这是index页面的内容</p>
      <p>这是index页面的内容</p>
      <p>这是index页面的内容</p>
      <p>这是index页面的内容</p>
  </body>
</html>

结果如下:

这里写图片描述

查看网页源码可以看到:

这里写图片描述

可以看到这两个元素的作用和我们jsp中的编译指令include十分相似,只是我们的include编译指令可以自己选择引入的外部文件放在被引入的jsp页面中的位置,而这两个元素则一个是引入到当前jsp页面头部,一个则是引入到当前jsp页面的底部。

二、表达式语言(EL)
     表达式语言是一种简化了的数据访问方式,使用它我们可以用简单的语法来实现对数据的访问。在jsp2中,建议使用表达式语言使得jsp页面格式一致,而避免使用jsp脚本。EL的使用语法是:${expression}。在了解如何使用之前,我们先了解一下他的内置对象,这些对象也是我们使用EL的关键。

pageContext: 获取当前页面的context对象,如jspcontext,servletcontext

pageScope:用于获取page范围内的属性的值

requestScope:用于获取request范围内的属性的值

sessionScopt:用于获取session范围内的属性的值

applicationScope:用于获取application范围内的属性的值

param:用于获取请求参数的值

paramValues:用于获取请求参数的集合(数组形式)

initParam:用于获取请求web应用的初始化参数(web.xml中的)

cookie:用于获取指定的cookie

从EL的内置对象看,基本上前台需要的数据都是可以获取到的。下面演示如何使用EL获取数据。

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<html>
  <head>
    <title>index</title>
  </head>
  <body>
      <%
          request.setAttribute("a","aaaaa");
          session.setAttribute("b","bbbbb");
      %>
      ${requestScope.a}    <!--或者${requestScope["a"]}-->
      ${sessionScope.b}
  </body>
</html>
这里写图片描述

以上的演示是EL的很简单的使用方法,也是利用了它的内置对象来完成对数据的访问获取。下面我们看看如何通过EL语法调用自定义函数,可以说扩充了调用自定义函数的功能使得EL更加灵活。但是允许EL调用的函数都必须是静态的(因为如果非静态的就需要创建对象来调用,违背了EL设计的初衷)。自定义函数主要有以下三个步骤:

  • 定义一个具有静态方法的类,并定义一些静态方法
  • 在标签库中配置可供调用的方法
  • 在jsp页面中使用自定义方法

第一步比较简单,就是定义一个具有静态方法的类,第二步有点像我们的自定义标签的过程,创建一个标签库,在taglib元素下,定义一个function子元素表示一个方法。

<?xml version="1.0" encoding="UTF-8"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>

    <uri>mytid</uri>
//定义了一个EL可调用的静态方法
    <function>
        <name>sayHello</name>  //指明方法名
        <function-class>Test_packge.SayHello</function-class>  //指明类名
        <function-signature>java.long.String sayHello(java.lang.String)</function-signature>  //指明方法的返回值,参数情况
    </function>
</taglib>
public class SayHello {

    public static String sayHello(String s){
        return "hello " + s;
    }
}

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<%@ taglib prefix="fun" uri="mytid" %>
<html>
  <head>
    <title>index</title>
  </head>
  <body>
    <p>${fun:sayHello("walker")}</p>
  </body>
</html>
这里写图片描述

我们可以看到在EL中调用自定义方法和使用自定义标签的语法很是类似,之上我们演示了一个EL调用自定义方法的完整流程,并由此可以看出,基本上EL可以调用一切所需资源,可以调用Javabean中方法获取数据库中的数据,也可以自定义类实现具体方法供EL调用。功能很是强大。

三、标签文件(Tag File)
     我们之前介绍过了自定标签的定义和使用,需要三个步骤。首先需要写一个标签处理类继承SimpleTag,然后实现doTag方法就就可以用来处理标签了,然后我们需要创建一个tld文件,在跟元素taglib中定义一个一个的tag元素,最后在jsp页面中使用。过程还是很麻烦的。jsp2.0之后,引入了标签文件,这是一个简化了的自定义标签的过程,实际上计算机内部还是将它转换成了我们自定义的三个步骤,在本节的结尾,我们会一起看看源码了解下编译器做了哪些操作。
     在Tag File文件中有5个编译指令,他们是:

  • taglib:用于导入其他的标签库
  • include:用于导入静态页面
  • tag:类似jsp页面中的page编译指令,用于指定页面的基本属性
  • attribute:用于设定自定义标签的属性,值是从jsp页面传入的
  • variable:可以提供jsp页面调用的变量

下面定义了一个简单的Tag file:

//在WEB-INF/tags 文件下创建一个myTag.tag标签文件
<%@ tag pageEncoding="UTF-8" import="java.util.*"%>

<%@ attribute name="bgColor"%>
<%@ attribute name="cellColor"%>
<%@ attribute name="title"%>
<%@ attribute name="bean"%>
<%@ variable name-given="time" variable-class="java.lang.String" scope="AT_BEGIN" %>

<% jspContext.setAttribute("time","now");%>
<table>
    <tr><td>${title}</td></tr>
    <%
        List<String> list = (List<String>)request.getAttribute("a");
        for(Object ele : list){%>
    <tr>
        <td bgColor="${cellColor}"><%=ele%></td>
    </tr>
    <%}%>
</table>
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>

<html>
  <head>
    <title>index</title>
  </head>
  <body>
      <%
          List<String> list = new ArrayList<String>();
          list.add("walker");
          list.add("yam");
          request.setAttribute("a",list);
      %>
      <tags:myTag bgColor="red" cellColor="blue" bean="a" title="测试" />
      <p><%=time%></p>

  </body>
</html>

我们需要始终知道的是,我们使用所有的标签,他们返回的结果都是页面片段,所以如果tag文件页面全是jsp语法就完全没有意义了。我们先从index页面看,前面引入标签库不用介绍了,只是这里需要知道我们引入的tagdir并不是这个标签文件(.tag),而是他的父目录。(这样做也是为了页面简洁,不用每个标签文件都引入一次),接着我们看,使用jsp脚本定义了一个list集合,并设置共享范围。

然后我们使用标签文件,和使用标签一样,这里的bgColor等属性是对应于我们myTag.tag文件中的attribute编译指令的,这样我们这边传入的属性的值就可以自动赋值到标签文件中了。

接下来我们看看标签文件,首先使用了tag 编译指令指定了页面片段的基本属性,如编码方式等。然后就是attribute 编译指令,用于接受jsp页面传入的属性值。至于这个variable变量的定义,我们先过(后面说)。紧接着是jsp脚本输出一个表格,不再赘述。我们看看结果:

这里写图片描述
这里写图片描述

     我们之前说过,标签文件是简化了的自定义标签,最终还是会被编译成Java类,和我们之前自定义标签时候写的标签处理类差不多。我们打开Tomcat/work....一直找到你的项目的tag文件夹,在里面会发现

这里写图片描述

我们打开这个标签文件,看到一坨代码。我们注意到:

  private java.lang.String bgColor;
  private java.lang.String cellColor;
  private java.lang.String title;
  private java.lang.String bean;
  public java.lang.String getBgColor() {
    return this.bgColor;
  }

  public void setBgColor(java.lang.String bgColor) {
    this.bgColor = bgColor;
    jspContext.setAttribute("bgColor", bgColor);
  }
....

我们看到这些代码是我们用编译指令attribute定义了的变量,经过编译之后,他们被创建成私有变量并配上set/get方法。这和我们在自定义标签处理类的时候是一样的,我们说这样可以保证jsp页面传入的属性的值可以自动的赋值给这些私有属性。(web容器干的)。我们还注意到:

这里写图片描述

这里也是一样的重写了doTag方法,同时还看到了标签文件中内置的对象有:

  • request
  • response
  • session
  • application
  • config
  • out
  • jspContext

绕了这么一圈,我们发现所谓的标签文件本质上还是我们那一套的自定义标签的流程,只是很大一部分内容交给了编译器。简化了我们程序员的工作。

     最后我们看看刚才跳过的编译指令variable,从上面的内容中我们知道,jsp页面可以通过属性传值给我们的标签文件,但是如果标签文件想要返回对象给jsp页面就需要使用到我们的variable编译指令。这个指令有几个属性需要注意下:

  • name-given ---指定了该变量的名称
  • variable-clas - ---指定了该变量的数据类型
  • scope ---指定该变量作用范围,这里有三个值

scope的第一个值可以是AT_BEGIN,该值表示此变量可以在标签体或者向下的代码中生效,第二值可以是NESTED,该值表示此变量只能出现在标签体中,第三个可以是AT_END,该值表示此变量只能从标签结束位置以后的代码中生效。可以看到第一个值的范围最大,包含了下面两个值的范围。定义完成之后,我们可以使用jspContext.setAttribute("time","now")方法为其赋值,这样我们的jsp页面就可以使用该变量了。

本篇文章至此结束,内容很简单,深入的内容还有待作者继续学习,希望能有大神指点纠正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,567评论 18 399
  • 1.学习内容 JSP技术入门和常用指令 JSP的内置对象&标签介绍 EL表达式&EL的内置对象 2.JSP技术入门...
    WendyVIV阅读 2,116评论 1 18
  • 这部分主要是与Java Web和Web Service相关的面试题。 96、阐述Servlet和CGI的区别? 答...
    杂货铺老板阅读 1,397评论 0 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 我是王小屋,做过十年的心理编辑和记者,其中的一个重要方向就是性心理学。因为这份工作,我采访过许多国内外重要的两性专...
    玲珑沙龙阅读 2,080评论 1 9