zoukankan      html  css  js  c++  java
  • 《Head First Servlets & JSP》-9-使用JSTL

    安装JSTL1.1的说明

    JSTL1.1不是JSP2.0规范的一部分,能访问servlet和JSP API并不意味着能访问JSTL。
    使用JSTL之前,需要将jstl.jar文件安装到Web应用的WEB-INF/lib目录,即每个Web应用都需要JSTL的一个副本。

    不用脚本实现一个循环——c:forEach

    servlet代码:

    • 使用脚本实现,很不好
      若想要在JSP页面中显示其中的各个元素,使用脚本的方式如下:
    • 使用JSTL c:forEach实现
      c:forEach标记提供了一种简单的方法来迭代处理数组和集合,如Collection、Map或者用逗号分隔的String。
      那么JSP页面代码变为:

      甚至可以使用可选的varStatus属性得到循环计数器:

      varStatus建立了一个新变量,其中保存javax.servlet.jsp.jstl.core.loopTagStatus的一个实例,而loopTagStatus类有一个count属性,这一切都在JSTL规范文档中。

      c:forEach标记还可以嵌套使用,如一个List中保存了若干数组,当遍历这些数组中的元素时…。

    使用c:if完成条件包含

    若对于一个评论页面,只有会员可以参与评论,非会员则只能浏览评论。
    评论列表(commentList.jsp):

    参与评论(inputComments.jsp):

    带有else的判断:c:choose和它的小伙伴c:when和c:otherwise


    毕竟c:if没有else,虽然可以使用多个if应对,但是很难看,况且这样一来也没有一个默认的选择(即otherwise的作用)。

    • JSP中部分代码:

      与Java中的switch有所不同,c:choose只能运行分支中的一个(包括when和otherwise),而switch在缺少break的时候可能运行多个分支。

    属性设置c:set标记

    鉴于jsp:setProperty标记只能设置bean的性质,而JSTL的c:set可以对bean、Map、变量等多个性质赋值。

    • 用c:set设置属性变量var

      注意,当值计算为null,变量会被删除。如原先有一个名为Fido的变量属性,而${person.dog}计算为null,这个Fido属性就会被删除,即使不指定scope,也会按照顺序在页面作用域、请求作用域、会话作用域、上下文作用域中找到并删除这个Fido!

    • 对bean和Map使用c:set

      target必须计算为一个对象!而不是表示属性名的String直接量。
      这意味着target需要一个EL表达式(如上)或者一个脚本表达式(<%= %>),或者jsp:attribute。

    c:remove来删除一个属性

    虽然c:set在值为null时可以删除属性,但是专门删除属性时用c:remove:

    复用页面的第三种方式——c:import

    • 复习一下前两种方式
      第一种方式:include指令
      <%@ include file="Header.html"%> 一般是静态的布局模板,如html页面,故用file属性。
      第二种方式:include标准动作
      <jsp:include page="Header.jsp"> 一般是JSP动态内容,故用page属性。
    • 第三种方式:JSTL的c:import标记
      <c:import url="http://www.google.com" /> 这里是url属性。
      与前两种方式不同,它可以超出当前容器范围之外!
    • 包含个性化参数c:param

    关于会话跟踪:URL重写/编码——c:url

    JSP中会话跟踪是自动发生的(除非把session属性指定为session=”false”)。但是,当客户不支持cookie的时候,需要重写URL的方式增加会话ID到URL。

    • 以前,在servlet中的URL重写是这样的
    • 在JSP中也可以做同样的事情
    • URL编码——c:param
      上述重写过程,没有特殊符号,因此不用进行URL编码。但是,若包含查询串,则难保不出现特殊符号,就像这样:

      那么在c:url的体中使用c:param,可完成编码:

      这样就可以查看编码后的URL:
      ${inputURL}

    建立自己的错误页面

    • 指定的错误页面errorPage.jsp
    • 会抛出异常的坏页面badPage.jsp:

      当访问badPage.jsp的时候,因为抛出异常,所以跳转到errorPage.jsp.
    • 通过DD中的error-page标记可以为整个Web应用指定多样化的错误页面
      一个普通的错误页面DD配置:

      更为明确的异常声明DD配置:

      或者根据HTTP状态码声明错误页面:

      DD 中的error-page是全局的,若某个JSP页面单独指定明确的errorPage page指令,那么容器就会优先使用page指令进行错误页面跳转。

    错误页面的一个额外隐式对象:exception

    若想要给用户提示错误信息时(通常不会提示这样的信息),则可以在错误页面中使用隐式对象exception:

    一般的页面不会有隐式对象exception的,只有明确使用page指令中的isErrorPage=”ture”属性的页面才有此隐式对象。

    想要自己捕捉异常,而不想抛出错误——c:catch

    • 使用c:catch标记捕捉异常
    • 自己捕捉的异常是可以访问的,只要定一个异常名字即可。即使本身不是异常页面(isErrorPage=”ture”):
    • 和try块一样,出现异常后,c:catch体中余下的部分不再运行

    使用非JSTL的标记库——定制库

    想要使用定制库,那么必须阅读TLD。当然,这只是使用它,若开发定制库(即开发支持标记的Java代码),不是这里的任务。

    • 理解TLD
      以下tld文件描述了一个标记:advice
    • 使用标记的JSP,及其与tld文件的对应关系

    • 注意rtexprvalue
      tag/attribute/rtexprvalue节点很重要,因为它会告诉你属性的值是在转换时计算,还是在运行时计算。
      若其值为false或未定义,那么属性值只能是一个String直接量,而不能是上图中的user=”${userName}”这种表达式!
      rtexprvalue不只是针对EL表达式,可以使用如下几种方式:

    1. EL表达式
    2. 脚本表达式
    3. attribute标准动作

      注意,即使tag/body-content声明为empty,仍可以使用jsp:attribute在标记的体中放属性!

    • 标记体body-conten里能放什么
      标记体body-conten中可以放如下值,只有当标记body-content元素值不是empty时,标记才能有体。

      对于没有体的标记(即body-conten为empty),有3中调用方法(包括上述的attribute标准动作):

    • taglib中的uri,只是一个名字
      上面的uri是randomThings,可知是一个名字。即使是uri=”http://java.sun.com/jsp/jstl/core”这种长串,也仅仅是一个名字,而不是一个位置。

    • tld文件的位置在哪里声明?
      在JSP2.0之前,会在web.xml中有个taglib-location项,但是现在不需要了。容器会在4个位置查找TLD:

    1. 直接在WEB-INF目录中查找
    2. 直接在WEB-INF的一个子目录中查找
    3. 在WEB-INF/lib下的JAR文件中的META-INF目录中查找
    4. 在WEB-INF/lib下的JAR文件中的META-INF目录的子目录中查找

    • 当JSP使用了多个标记库
      每个TLD要有一个单独的taglib指令;
      确保taglib指令名是唯一的;
      不要使用保留前缀如jsp/jspx/java/javax/serlvet/sun/sunw等

    标记处理器、TLD和JSP关系

    定制标记处理器

    上面是如何使用advice定制标记的,那么现在稍微看看该标记的支持代码是怎么写的。

    • 完成标记工作的Java类foo.AdvisorTagHandler.java
      这个简单的标记处理器扩展了SimpleTagSupport,实现了两个关键方法:doTag()和setUser()。
      doTag()是完成具体工作的方法,setUser()是接受属性值的方法。详情如下:

    EL函数 vs 标记处理器

    • 都是Java类
    • 都需要放在WEB-INF/classes文件下的某个路径下
    • 都要在TLD文件中进行映射
    • EL函数在TLD中的映射是节点
    • 标记处理器在TLD中的映射是节点
    • EL函数可以定义任意名称的静态方法
    • 标记处理器方法名必须是doTag()
  • 相关阅读:
    开源项目
    [Accessibility] Missing contentDescription attribute on image [可取行]失踪contentDescription属性图像
    Android 布局 中实现适应屏幕大小及组件滚动
    EF 错误记录
    EasyUI 加载时需要显示和隐藏 panel(面板)内容破版问题
    IE 报表缩放后页面破版
    VS 2017 引入nuget 问题
    SSRS 报表显示页面 asp net session丢失或者找不到 asp net session has expired or could not be found()
    log4net 配置
    网站
  • 原文地址:https://www.cnblogs.com/myitroad/p/6192531.html
Copyright © 2011-2022 走看看