以前一哥们跟我说 他项目经理写的自定义标签可以 c:foreach 进行循环 感觉好高端的感觉啊 ! 呵呵呵~~ 当时觉得自己写的标签好像从来没有这种功能啊。。。
但是因为没有代码 我也不知道是怎么回事,也没有去细想! 今天忽然看 项目里面的代码 看到了 tld 就复习了下,百度了些资料! 发现知识得多复习啊,不用就忘了,也许是我学的不够好吧,呵呵,很多细节都不知道了! 比如今天翻开自己以前写的笔记,记录的是 enum跟Enum的关系, 一看根本没印象了 呵呵呵!
tld的 文章 很多 : 其实都差不多 因为tld的知识点就那么点 呵呵 因为大家都写了 我就不重复了 下面这个地址里面 写的很详细 http://blog.youkuaiyun.com/liaoxiaohua1981/article/details/6856307
这个文章也非常不错 特别详细:http://ar.newsmth.net/thread-5d499b1fbe9e50.html(这里有很多我们不知道,平时不会用到的细节知识,相当于taglib的文档)
我发现啊,很多时候还是太懒了,比如说现在,我看taglib的 文档 有些地方不是太清楚 他们文章上写的也有点不大好理解,其实只要自己写个例子就ok了~!
经过测试 发现
<required>false</required><!--是否是必填选项 -->
如果参数的 required 为 true的时候如果你不填这个参数的话 那么编译器会告诉你错误的!
如果rtexprvalue 为false的话
<attribute><!---这里表示的是这个tag的一个参数 -->
<name>test</name><!--这个参数的名字 -->
<required>true</required><!--是否是必填选项 -->
<rtexprvalue>false</rtexprvalue><!--这个参数的值是否可以写入,换句话说 就是这个参数是否可以动态赋值 -->
</attribute>
jsp中 这么写
<%
String str = "123";
%>
<test:test test="<%=str %>"/>
会爆如下错误:
org.apache.jasper.JasperException: /testTagLib.jsp (line: 14, column: 0) According to TLD or attribute directive in tag file, attribute test does not accept any expressions
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:42)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:408)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:149)
at org.apache.jasper.compiler.Validator$ValidateVisitor.checkXmlAttributes(Validator.java:1240)
at org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:875)
at org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1539)
at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2376)
at org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2428)
at org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2434)
at org.apache.jasper.compiler.Node$Root.accept(Node.java:475)
at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2376)
at org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1795)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:217)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:373)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
说明 rtexprvalue 设置为false 表示不接受 表达式赋值 表达式 当然如下方式也不行
<%
String str = "123";
request.setAttribute("test", "112");
%>
<%-- <test:test test="<%=str %>"/> --%>
<test:test test="${test}"/>
接下来让我头疼的问题来了! 既然 如果 rtexprvalue 设置为 false 是不接受 EL表达式 或者 直接小脚本写java代码传值的 可是 我们现在的项目里面 把c.tld 给拿出来了,放在 /WEB-INF/tag/jstl/ 下面
而且配置的 也是指向这里的:
<%@ taglib uri="/WEB-INF/tag/jstl/c.tld" prefix="c" %>
可是为什么我用 EL表达式 却是可以的呢~?
<tag>
<name>forEach</name>
<tag-class>org.apache.taglibs.standard.tag.el.core.ForEachTag</tag-class>
<tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
<body-content>JSP</body-content>
<description>
The basic iteration tag, accepting many different
collection types and supporting subsetting and other
functionality
</description>
<attribute>
<name>items</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>begin</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>end</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>step</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>varStatus</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
可是
<c:forEach items="${strs}" var="str2">
<c:out value="${str2}"></c:out>
</c:forEach>
这样写是没有任何问题的!! ! 项目是在 idea里面跑的 我把 c.tld 拉到我 自己的一个 小项目 里面去 报错了, 因为一直用的 idea 基本没怎么用eclipse 所以我还以为是eclipse坑爹了呢~ 但是 如果写成 :
<c:forEach items="<%=request.getAttribute("strs")%>" var="str2">
<c:out value="${str2}"></c:out>
</c:forEach>
这是要报错的!!!
碰到问题! 越想越想不通! 所以想找人问问! 我看到我们公司的架构师在,我就去问他 我说我碰到个问题!! 哎 他一副很不愿搭理的样子说 “碰到问题自己查啊,我哪记得那么多啊!“ 我又是自尊心很强的人! 看到他这样子 二话不说 直接走了! 自己解决就自己解决 有啥好拽的,我只是觉得他经验丰富也许以前碰到过类似的问题! 其实还是我自己心理有问题了, 这有啥好不爽的呢,他帮我 我要谢谢他,不帮我 也无可厚非了! 而且也许是我自尊心太强了吧,他也许就是这样的性格! 算了 不管了! 回去之后 自己一头扎进去猛搞了一顿! 终于搞清楚了!
首先得感想网上的几篇好文章:
http://www.cnblogs.com/panjun-Donet/articles/1179262.html
http://www.iteye.com/topic/155354
http://www.iteye.com/topic/231840
web.xml 的 doctype的申明 申明的是 servlet 的版本 !
如下:
servlet 2.2
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/dtd/web-app_2_2.dtd">
servlet 2.3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
servlet 2.4
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
servlet 2.5
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
在2.3及其以前的版本 是不支持 EL 表达式!
除非加了下面代码
<%@ page isELIgnored="false" %>
现在就可以解释那些怪异现象了:
我们项目里面配置的 是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
也就是2.3版本了!
系统把 EL 表达式当做一个 普通字符串了!
当我加上
<%@ page isELIgnored="false" %>
果然报错了!! 哈哈哈!
现在的问题又来了
为什么作为 字符串 还能够正常的循环呢! ?
因为 我们用 jstl的 版本是1.2的 里面 有这么一句话:
Object r = ExpressionEvaluatorManager.evaluate("begin", this.begin_, Integer.class, this, this.pageContext);
这个话 干嘛的呢 就是 解释 EL表达式的!! !
这下终于真相大白了!!!
接下来讲讲 tld 中的 TEI-CLASS 是啥玩意
这个就是用来验证的 在编译期 或者说写代码的时候 就能够知道 传递的是不是有问题 这样就可以 将错误 扼杀在 摇篮里!!!
如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>test-tag</short-name>
<uri>/WEB-INF/tag/test.tld</uri>
<description>
A simple tag library
</description>
<validator>
<validator-class>com.ausky.taglib.TestValidator</validator-class>
</validator>
<tag>
<name>test</name><!--tag的名字 -->
<tag-class>com.ausky.taglib.TestTag</tag-class><!--tag对应的java类的名字 -->
<tei-class>com.ausky.taglib.TestTEI</tei-class>
<body-content>empty</body-content>
<attribute><!---这里表示的是这个tag的一个参数 -->
<name>test</name><!--这个参数的名字 -->
<required>true</required><!--是否是必填选项 -->
<rtexprvalue>true</rtexprvalue><!--这个参数的值是否可以写入,换句话说 就是这个参数是否可以动态赋值 -->
</attribute>
</tag>
</taglib>
package com.ausky.taglib;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
/**
*
* @author xn-hyao-01
*
*/
public class TestTag extends TagSupport {
private static final long serialVersionUID = 7385843353583961842L;
private String test;
public String getTest() {
return test;
}
public void setTest(String test) {
System.out.println("test value is " + test);
try{
// Object o= ExpressionUtil.evalNotNull("test","test","${i}",Object.class,this,this.pageContext);
// ExpressionEvaluatorManager.evaluate("test", "${i}", Object.class,this,this.pageContext);
}catch (Exception ex){
}
this.test = test;
}
@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
return super.doAfterBody();
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return super.doEndTag();
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return super.doStartTag();
}
@Override
public void release() {
// TODO Auto-generated method stub
super.release();
}
}
package com.ausky.taglib;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.ValidationMessage;
import javax.servlet.jsp.tagext.VariableInfo;
public class TestTEI extends TagExtraInfo {
@Override
public boolean isValid(TagData data) {
Object o = data.getAttribute("test");
return o!=null;
}
@Override
public VariableInfo[] getVariableInfo(TagData data) {
// TODO Auto-generated method stub
return super.getVariableInfo(data);
}
@Override
public ValidationMessage[] validate(TagData data) {
// TODO Auto-generated method stub
return super.validate(data);
}
}
这下 tei-class 也理解了!
接下来 讲讲
tld 中的 validator
这个是做啥的呢 :
上面有篇文章里面讲解了! 这个我也没怎么具体搞 呵呵呵~~ 就稍微看了下
下面是 原文里面的一段 原话 http://tech.ccidnet.com/art/3737/20030715/459917_1.html
JSP1.2
JSP1.2中引入一个新的标记检验方法,定义了一个新类TagLibraryValidator,并且可以由此派生出检验标志的类,大多数情况下仅使用这个类的validate()方法,它有三个参数:prefix(在taglib指令中定义的前缀);uri(TLD文件中的URI);page(JSP页的PageData XML版本),validate()方法返回值为null时表示验证成功,否则返回的String类型将是一个错误信息。
当validator在TLD文件中定义时,它应该放在<tag>元素定义的外面,因为它是用来处理验证标记库中的所有标记的。
<validator><validator-class></validator-class></validator>。
比较JSP1.2和JSP1.1中的方法:
TagLibraryValidator比TEI类更全面,可以用来检测整个网页,而不仅仅是标记本身,可以用来处理标记间的合作,并且这种方法可以用来通知程序员错误出在哪里,但是同时它的方法也比TEI类的方法复杂多了,因为它需要遍历整个XML版本的JSP(完成getAttributeValue方法)。
就是说 它就是 TEI-CLASS 的 升级版!
我写了个 小测试:
package com.ausky.taglib;
import javax.servlet.jsp.tagext.PageData;
import javax.servlet.jsp.tagext.TagLibraryValidator;
import javax.servlet.jsp.tagext.ValidationMessage;
/**
* Created with IntelliJ IDEA.
* User: xn-hyao-01
* Date: 14-2-21
* Time: 上午11:22
* To change this template use File | Settings | File Templates.
*/
public class TestValidator extends TagLibraryValidator {
@Override
public ValidationMessage[] validate(String prefix, String uri, PageData page) {
return super.validate(prefix, uri, page); //To change body of overridden methods use File | Settings | File Templates.
}
}
我打个断点 看了下 page 里面到底是啥
<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root
version="2.0"
xmlns:c="urn:jsptld:/WEB-INF/tag/jstl/c.tld"
xmlns:ww="urn:jsptld:/WEB-INF/tag/wildwolf/wildwolf.tld"
xmlns:ww-el="http://www.sinitek.com/wildwolf/el"
xmlns:accounttool="urn:jsptld:/WEB-INF/tag/account/accounttool.tld"
xmlns:fund-tools="urn:jsptld:/WEB-INF/tag/trade/fundinfo_el.tld"
xmlns:fmt="urn:jsptld:/WEB-INF/tag/jstl/fmt.tld"
xmlns:BankInfo="urn:jsptld:/WEB-INF/tag/bank/bankinfo.tld"
xmlns:query-tools="urn:jsptld:/WEB-INF/tag/trade/query.tld"
xmlns:capital="urn:jsptld:/WEB-INF/tag/mycapital/capitalcommon.tld"
xmlns:bulletin="urn:jsptld:/WEB-INF/tag/bulletin/bulletin.tld"
xmlns:test="urn:jsptld:/WEB-INF/tag/test.tld"
xmlns:jsp="http://java.sun.com/JSP/Page"
jsp:id="0"
>
<jsp:directive.page
jsp:id="1"
pageEncoding="UTF-8"
contentType="text/html;charset=UTF-8"
/>
<jsp:directive.page
jsp:id="2"
import="java.util.ArrayList"
/>
<jsp:text
jsp:id="3"
>
<![CDATA[
]]>
</jsp:text>
<jsp:directive.page
jsp:id="4"
import="java.util.List"
/>
<jsp:text
jsp:id="5"
>
<![CDATA[
]]>
</jsp:text>
<jsp:directive.page
jsp:id="6"
language="java"
/>
<jsp:text
jsp:id="7"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="8"
>
<![CDATA[
]]>
</jsp:text>
<jsp:directive.page
jsp:id="9"
language="java"
/>
<jsp:text
jsp:id="10"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="11"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="12"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="13"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="14"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="15"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="16"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="17"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="18"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="19"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="20"
>
<![CDATA[
]]>
</jsp:text>
<jsp:scriptlet
jsp:id="21"
>
<![CDATA[
String trade_title = "电信合作项目";
]]>
</jsp:scriptlet>
<jsp:text
jsp:id="22"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="23"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="24"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="25"
>
<![CDATA[
<html>
]]>
</jsp:text>
<jsp:text
jsp:id="26"
>
<![CDATA[
<head>
]]>
</jsp:text>
<jsp:text
jsp:id="27"
>
<![CDATA[
<title>]]>
</jsp:text>
<jsp:expression
jsp:id="28"
>
<![CDATA[
trade_title]]>
</jsp:expression>
<jsp:text
jsp:id="29"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="30"
>
<![CDATA[
</title>
]]>
</jsp:text>
<jsp:directive.page
jsp:id="31"
language="java"
/>
<jsp:text
jsp:id="32"
>
<![CDATA[
]]>
</jsp:text>
<jsp:directive.page
jsp:id="33"
import="com.sinitek.sfm.trade.chinatele.bean.ICTLoginBean"
/>
<jsp:scriptlet
jsp:id="34"
>
<![CDATA[
ICTLoginBean loginBean = (ICTLoginBean) session.getAttribute(ICTLoginBean.sessionID);
if (loginBean == null)
{
]]>
</jsp:scriptlet>
<jsp:text
jsp:id="35"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="36"
>
<![CDATA[
<script>
alert("用户已登出,或超时,请重新登录");
location.href = "login.jsp";
]]>
</jsp:text>
<jsp:text
jsp:id="37"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:scriptlet
jsp:id="38"
>
<![CDATA[
}
]]>
</jsp:scriptlet>
<jsp:text
jsp:id="39"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="40"
>
<![CDATA[
<script type="text/javascript" src="../framework/js/jquery.js" charset="utf-8">]]>
</jsp:text>
<jsp:text
jsp:id="41"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="42"
>
<![CDATA[
<script type='text/javascript' src='../dwr/engine.js'>]]>
</jsp:text>
<jsp:text
jsp:id="43"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="44"
>
<![CDATA[
<script type="text/javascript" src="../framework/js/placeholder.js">]]>
</jsp:text>
<jsp:text
jsp:id="45"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="46"
>
<![CDATA[
<script type="text/javascript" src="../framework/js/jquery.bgiframe.js">]]>
</jsp:text>
<jsp:text
jsp:id="47"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="48"
>
<![CDATA[
<script type="text/javascript" src="../framework/js/loading.js">]]>
</jsp:text>
<jsp:text
jsp:id="49"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="50"
>
<![CDATA[
<script type="text/javascript" src="../framework/js/jquery.cookie.js">]]>
</jsp:text>
<jsp:text
jsp:id="51"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="52"
>
<![CDATA[
<script type="text/javascript" src="../framework/js/common.js">]]>
</jsp:text>
<jsp:text
jsp:id="53"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="54"
>
<![CDATA[
<script type="text/javascript" src="../dwr/interface/ChinaTeleDwr.js">]]>
</jsp:text>
<jsp:text
jsp:id="55"
>
<![CDATA[
</script>]]>
</jsp:text>
<jsp:text
jsp:id="56"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="57"
>
<![CDATA[
<script type="text/javascript" src="../dwr/interface/UserLoginDwr.js">]]>
</jsp:text>
<jsp:text
jsp:id="58"
>
<![CDATA[
</script>
]]>
</jsp:text>
<jsp:text
jsp:id="59"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="60"
>
<![CDATA[
</head>
]]>
</jsp:text>
<jsp:text
jsp:id="61"
>
<![CDATA[
<body>
]]>
</jsp:text>
<jsp:scriptlet
jsp:id="62"
>
<![CDATA[
List<String> strs = new ArrayList<String>();
strs.add("1");
strs.add("2");
strs.add("3");
strs.add("4");
String test = "11";
int i = 1;
request.setAttribute("strs", strs);
request.setAttribute("i", i);
request.setAttribute("strs2", "111");
]]>
</jsp:scriptlet>
<jsp:text
jsp:id="63"
>
<![CDATA[
临时首页
]]>
</jsp:text>
<jsp:text
jsp:id="64"
>
<![CDATA[
<button onclick="$('#logoutForm').submit()">退出]]>
</jsp:text>
<jsp:text
jsp:id="65"
>
<![CDATA[
</button>
]]>
</jsp:text>
<jsp:text
jsp:id="66"
>
<![CDATA[
<form id="logoutForm" action="UserLoginAction.do?method=logout" method="post">
11111121
111
]]>
</jsp:text>
<jsp:text
jsp:id="67"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="68"
>
<![CDATA[
</form>
]]>
</jsp:text>
<test:test
test="${i}"
jsp:id="69"
/>
<jsp:text
jsp:id="70"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="71"
>
<![CDATA[
]]>
</jsp:text>
<jsp:text
jsp:id="72"
>
<![CDATA[
</body>
]]>
</jsp:text>
<jsp:text
jsp:id="73"
>
<![CDATA[
</html>]]>
</jsp:text>
</jsp:root>
果然是要遍历怎么jsp啊!! !!
对了 最后说一点 validator 或者 TEI-CLASS 都是只执行一次!!!
差点忘记时候 开始时的问题了~~:
类似于下面的功能:
<test:list id="books" name="yuwen"/>
<c:foreach items="${books}" var="book"></c:foreach>
其实这个 也不需要 variable 属性了 直接pageContext.getReqest().setAttribute();
那什么时候 需要呢 ~~
<jsp:getProperty property="name" name="test2"/>
这个就需要使用 variable 属性了 不然它都不知道 test2 在什么时候定义的!!
<tag>
<name>test</name><!--tag的名字 -->
<tag-class>com.ausky.taglib.TestTag</tag-class><!--tag对应的java类的名字 -->
<tei-class>com.ausky.taglib.TestTEI</tei-class>
<body-content>empty</body-content>
<!-- <variable>
<name-from-attribute>params</name-from-attribute>
<variable-class>com.ausky.taglib.TestBean</variable-class>
<scope>AT_BEGIN</scope>
</variable> -->
<attribute><!---这里表示的是这个tag的一个参数 -->
<name>test</name><!--这个参数的名字 -->
<required>true</required><!--是否是必填选项 -->
<rtexprvalue>true</rtexprvalue><!--这个参数的值是否可以写入,换句话说 就是这个参数是否可以动态赋值 -->
</attribute>
<attribute><!---这里表示的是这个tag的一个参数 -->
<name>params</name><!--这个参数的名字 -->
<required>true</required><!--是否是必填选项 -->
<rtexprvalue>false</rtexprvalue><!--这个参数的值是否可以写入,换句话说 就是这个参数是否可以动态赋值 -->
</attribute>
</tag>
<test:test test="122" params="test2"/>
<jsp:getProperty property="name" name="test2"/>
TestBean test = new TestBean();
test.setAddress("111");
test.setName("1112");
pageContext.getRequest().setAttribute(params,test);
呵呵 后面说的有点语无伦次了!! 反正后面的也不大需要!! 就是说 variable 属性说明了的话 这样jsp编译的时候 就可以知道了!!! 而 我们 c:foreach 的时候 是不需要预编译知道的所以有没有 variable 都一样!!
OK 结束!