• Head First Servlets & JSP 学习笔记 第九章 —— 使用JSTL


    JSTL1.1 不是JSP2.0规范的一部分!你能访问Servlet和JSP API 不意味着你能访问JSTL!

    使用JSTL之前,需要将两个文件("jstl.jar" 和 "standard.jar")放在自己Web应用的WEB-INF/lib目录中。

    将Html标记以纯文本显示出来,而不是解释标记渲染页面:<c:out />

    1 <c:out value='${pageContent.rawHTML}' escapeXml='false' />   //escapeXml=false,所有的Html标记都会得到计算,而不是作为文本显示
    2 <c:out value='${pageContent.currentTip}' escapeXml='true' />  //escapeXml=true,则所有的Html标记都是以纯文本显示出来,escapeXml默认值为true

    使用<c:out />标记来输出所有的用户串,可以避免跨网站攻击或跨网站脚本攻击

    给<c:out />标记提供一个默认值:

    1 <b>Hello  <c:out value='${user}' default='guest' />.</b>  //当value计算结果为null时,就会输出默认值。这是<c:out />标记的优势,因为EL和JSP表达式当计算结果为null时,只能打印一个空格

    实现循环:<c:forEach />

    1 <table>
    2     <c:forEach var="movie" items="${movieList}"> //将movieList集合中的每一个元素依次赋给变量movie,然后打印到表格中
    3         <tr>
    4             <td>${movie}</td>
    5         </tr>
    6     </c:forEach>
    7 </table>

    可选参数varStatus

     1 <table>
     2     <c:forEach var="movie" items="${movieList}" varStatus="movieLoopCount" >
     3         <tr>
     4             <td>Count: ${movieLoopCount.count}</td>     //varStatus参数的count属性,打印计数器的当前值
     5         <tr>
     6         <tr>
     7             <td>${movie}</td>
     8         </tr>
     9     </c:forEach>
    10 </table>

    <c:forEack />标记还可以进行嵌套:

    servlet代码:

    1 String[] movies1 = {"Matrix Revolutions", "Kill Bill", "Boondock Saints"};
    2 String[] movies2 = {"Amelie", "Return of the King", "Mean Girls"};
    3 java.util.List movieList = new java.util.List ArrayList();
    4 movieList.add(movies1);
    5 movieList.add(movies2);
    6 
    7 request.setAttribute("movieList", movieList);

    JSP:

    1 <table>
    2     <c:forEach var="listElement" items="${movieList}"> //外部循环,将movieList数组列表中的元素(一共2个元素)赋给listElement
    3         <c:forEach var="movie" items="${listElement}"> //内部循环,依次获取外部循环的元素listElement,将listElement中的元素赋给movie,打印到表格中
    4             <tr>
    5                 <td>${movie}</td>
    6             </tr>
    7         </c:forEach>
    8     </c:forEach>
    9 </table>

    使用<c:if />完成条件包含:

    同一个页面,注册用户和非注册用户看到的内容不一样。注册用户能添加评论。

    1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    2 
    3 <c:if test="${userType eq 'member'}">
    4     <jsp:include page="inputComments.jsp"/>
    5 </c:if>

    如果一个if不行,需要else,可以用<c:choose/>标记

     1 <c:choose>
     2     <c:when test="${userPref == 'performance'}">
     3         Now you can stop even if you <em>do</em> drive insanely fast.
     4     </c:when>
     5     
     6     <c:when test="${userPref == 'safety'}">
     7         Our brakes will never lock up, no matter how bad a driver you are.
     8     </c:when>
     9     
    10     <c:when test="${userPref == 'maintenance'}">
    11         Lost your tech job? No problem--you won't have to service these brakes for at least three years.
    12     </c:when>
    13     
    14     <c:otherwise>
    15         Our brakes are the best.
    16     </c:otherwise>
    17 </c:choose>

    <c:set />

    <jsp:setProperty>标记只能做一件事情,就是设置bean的性质。

    <c:set/>标记可以做得更多。<c:set/>有两个版本:var版本和target版本。两个版本又都有两种形式:有体和没体。

    var版本:

    1 <c:set var="userLevel" scope="session" value="Cowboy"/>
    2 
    3 <c:set var="Fido" value="${person.dog}"/>
    4 
    5 <c:set var="userLevel" scope="session">   //有体
    6     Sheriff, Bartendar, Cowgirl
    7 </c:set>

    target版本:

    1 <c:set target="${PetMap}" property="dogName" value="Clover" />
    2 
    3 <c:set target="${person}" property="name">   //有体
    4     ${foo.name}
    5 </c:set>

    使用<c:remove/>标记删除一个变量

     1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     2 <html><body>
     3 
     4 <c:set var="userStatus" scope="request" value="Brilliant" />
     5 
     6 userStatus: ${userStatus} <br>
     7 
     8 <c:remove var="userStatus" scope="request" /> //scope是可选的,但是如果没有指定scope,就会从所有作用域中删除userStatus属性
     9 
    10 userStatus is now: ${userStatus}
    11 
    12 </body></html>

    使用<c:import/>标记包含内容:

    之前已经知道了两种:<%@ include file="xx.jsp" %>include指令  <jsp:include page="xx.jsp" />include动作

    现在再学一招:<c:import />JSTL标记

    1 <c:import url="http://www.wickedlysmart.com/skyler/horse.html" />  //动态:在请求时,将URL属性指定的内容增加到当前页面。它与<jsp:include/>相似,但是更强大、更灵活。

    使用<%@ include file="xx.jsp">或者<jsp:include page="xx.jsp" />只能包含当前Web应用之内的页面。但是<c:import />还可以把容器之外的内容包含进来。

    还有<c:param/>标记:

     1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     2 <html><body>
     3 
     4 <c:import url="Header.jsp">
     5     <c:param name="subTitle" value="We take the sting out of SOAP." />
     6 </c:import>
     7 
     8 <br>
     9 
    10 <em>Welcome to our Web Services Support Group.</em><br><br>
    11 Contact us at : ${initParam.mainEmail}
    12 </body></html>

    <c:url/>标记可以满足所有超链接需求:

    客户禁用cookie后,容器会自动地完成URL重写。但是如果使用Servlet,还必须对URL编码:

     1 //Servlet的URL重写
     2 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
     3     response.setContentType("text/html; charset=utf-8");
     4     PrintWriter out = request.getWriter();
     5     HttpSession session = request.getSession();
     6     
     7     out.println("<html><body>");
     8     out.println("<a href="" + response.encodeURL("/BeerTest.do") + "">click</a>"); //在Java中写Html真的是很麻烦
     9     out.println("</body></html>");
    10 }

    那如果使用<c:url/>标记呢:

    1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    2 <html><body>
    3 
    4 This is a hyperlink with URL rewriting enabled.
    5 
    6 <a href="<c:url value='/inputComments.jsp'/>"Click here</a>
    7 
    8 </body></html>

    <c:url />标记所做的只是URL重写,URL通常都需要编码:

    1 <c:url value="/inputComments.jsp" var="inputURL">
    2     <c:param name="firstName" value="${first}" /> //现在<c:param>标记负责对URL进行编码工作
    3     <c:param name="lastName" value="${last}" />
    4 </c:url>    

    建立自己的错误页面:(errorPage)

    让发生的错误对用户更加友好!而不是显示一堆跟踪错误(自己都不想看)

    1 <%@ page isErrorPage="true" %>      //向容器做出确认,这个是正式的错误页面
    2 <html><body>
    3 <strong>Bummer.</strong>
    4 <img src="images/bummerGuy.jpg" />
    5 </body></html>
    1 <%@ page errorPage="errorPage.jsp" %>  //告诉容器,出问题了就把请求转发到errorPage.jsp
    2 <html><body>
    3 About to be bad...
    4 <% int x = 10 / 0; %>
    5 </body></html>

    那么问题来了,要给一个一个的JSP加上<%@ page errorPage="errorPage.jsp" %>也是很麻烦的!

    可以使用<error-page>DD标记,为整个Web应用配置错误页面:(<%@ page errorPage="errorPage.jsp" %>优先级高于DD中的<error-page>标记)

    在DD(web.xml)中,可以根据<exception-type>或HTTP状态码<error-code>声明错误页面。

     1 <error-page>
     2     <exception-type>java.lang.Throwable</exception-type>  //普通的错误
     3     <location>/errorPage.jsp</location>
     4 </error-page>
     5 
     6 <error-page>
     7     <exception-type>java.lang.ArithmeticException</exception-type>  //更加明确的错误
     8     <location>/arithmeticError.jsp</location>
     9 </error-page>
    10 
    11 <error-page>
    12     <error-code>404</error-code>  //404错误
    13     <location>/notFoundError.jsp</location>    //<location>必须以/开头,无论<exception-type>还是<error-code>
    14 </error-page>

    错误页面得到一个额外的对象:exception:

    错误页面实际上就是处理异常的JSP,所以容器为这个页面提供了一个额外的exception对象。exception隐式对象只对错误页面可用(有明确定义的page指令:<%@ page isErrorPage="true" %>)

    1 <%@ page isErrorPage="true" %>
    2 <html><body>
    3 <strong>Bummer.</strong><br>
    4 
    5 You caused a ${pageContext.exception} on the server.<br>    //这样会得到更加明确的错误类型,因为调用了exception隐式对象
    6 
    7 <img src="images/bummerGuy.jpg" />
    8 </body></html>

    <c:catch />标记 —— 就像try/catch.......

    <c:catch />标记,把有风险的标记或表达式包起来。因为倘若不这样,就会抛出异常,默认的错误处理机制就会插手!

     1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     2 <%@ page errorPage="errorPage.jsp" %> //这是一个正式指定了错误页面,可以使用exception隐式对象
     3 <html><body>
     4 
     5 About to do a risky thing: <br />
     6 
     7 <c:catch>
     8     <% int x = 10 / 0; %>  //一个可预见的错误
     9 </c:catch>
    10 
    11 If you see this, we survived.  //因为使用了<c:catch>标记,遇到异常立即跳过,所以我们得救了
    12 
    13 </body></html>

    理解TLD:(Tag Library Descriptor,TLD,标记库描述文件)

    标记库描述文件TLD,描述了两个主要内容:定制标记和EL函数。

    1.TLD,标记库描述文件可以放到WEB-INF的任何子目录中去!

    2.在部署描述文件(DD,web.xml)中使用<taglib>元素定义TLD(标记库描述文件)

    1 <taglib>
    2     <taglib-uri>myTags</taglib-uri>
    3     <taglib-location>/WEB-INF/myTags.tld</taglib-location>
    4 </taglib>
  • 相关阅读:
    打卡规则小模块设计
    json和ajax学习
    求两个数的百分比&时间格式化&ajax返回json
    spring security运行流程图(转)
    DelegatingFilterProxy作用浅析
    网站URL重写(Java UrlRewrite 的使用)
    JVM的常用的调优策略和垃圾回收算法及Tomcat的常用调优参数
    JQuery 的Ajax的使用
    servlet程序HTTP Status 500
    CanvasRenderingContext2D.drawImage()无效,not working
  • 原文地址:https://www.cnblogs.com/czp2bconfident/p/8909412.html
Copyright © 2020-2023  润新知