JavaWeb學習之JSTL自定義標簽庫的使用、JSTL自定義函數庫(7)


一、自定義標簽,步驟
* 確定需求
* <my:date /> 輸出當前系統的時間 yyyy-MM-dd hh:mm:ss:SSS
* 編寫Java類
新建包名:com.yxl.tag
,新建類MyDateTag,實現SimpleTag接口
* 只要與此接口有關的實現類,javax.servlet.jsp.tagext.JspTag
* 需要實現具體的接口
* javax.servlet.jsp.tagext.SimpleTag
,簡單標簽,JSP2.0**,選擇這個
* javax.servlet.jsp.tagext.Tag,經典標簽
package com.yxl.tag
;

import java.io.IOException
;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspContext
;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;

public class MyDateTag implements SimpleTag {

public MyDateTag(){
System.out.println(
"默認構造");
}

private PageContext pageContext
;

/**
*
1、被調用的方法,tomcat調用
*/
public void setJspContext(JspContext pc) {
// System.out.println(pc)
;
// System.out.println("setJspContext");
this.pageContext = (PageContext) pc;

}

/**
*
2、tomcat調用
* 建議,在doTage方法中完成整個tag的功能
* 需要再doTage方法之前,完成准備工作
*/
public void doTag() throws JspException
, IOException {
// System.out.println(
"doTag");
//輸出當前系統的時間 yyyy-MM-dd hh:mm:ss:SSS
SimpleDateFormat format
= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
String date = format.format(new Date());
//將獲得的時間輸出到瀏覽器
this.pageContext.getOut().print(date)
;

}

@Override
public JspTag getParent() {
// TODO Auto-generated method stub
return null
;
}

@Override
public void setJspBody(JspFragment arg0) {
// TODO Auto-generated method stub

}



@Override
public void setParent(JspTag arg0) {
// TODO Auto-generated method stub

}

}

* 編寫tld文件
在WEB-INF下新建文件夾tld,在tld文件夾下新建mytag.tld
* tld文件是xml文檔
* 擴展名為*.tld
* 位置:必須放置到WEB-INF目錄下
* 內容:
<taglib xmlns
="http://java.sun.com/xml/ns/javaee"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version
="2.1">
<!-- 確定當前標簽庫的版本 -->
<tlib-version>
1.0</tlib-version>
<!-- 建議引入當前便簽庫是,使用的簡寫 @taglib prefix
="my" -->
<short-name>my</short-name>
<!-- 為當前標簽庫配置文件,起一個名稱
* 內容:自定義,全球唯一
-->
<uri>http://www.yxl.cn/jsp/mytag</uri>

<!-- <my:date / > 注冊標簽 -->
<tag>
<!-- 確定標簽名稱 -->
<name>date</name>
<!-- 確定實現類 -->
<tag-class>com.yxl.tag.MyDateTag</tag-class>
<!-- 格式化當前標簽的body內容
* empty:當前標簽沒有標簽體
-->
<body-content>empty</body-content>

</tag>


</taglib>
* 在JSP頁面引入
* <%@ taglib uri
="http://www.yxl.cn/jsp/mytag" prefix="my"%>
* 測試
* <my:date />

二、案例
* 需求:<my:maxVal num1
="12" num2="13" />
package com.yxl.tag
;

import java.io.IOException
;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspContext
;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;

public class MyMaxValueTag implements SimpleTag {

public MyMaxValueTag() {
System.out.println(
"默認構造");
}

private PageContext pageContext
;
private Integer num1;
private Integer num2;

// num1
public void setNum1(Integer num) {
this.num1
= num;
}

public void setNum2(Integer num) {
this.num2
= num;
}

/**
*
1、被調用的方法,tomcat調用
*/
public void setJspContext(JspContext pc) {
// System.out.println(pc)
;
// System.out.println("setJspContext");
this.pageContext = (PageContext) pc;

}

/**
*
2、tomcat調用 建議,在doTage方法中完成整個tag的功能 需要再doTage方法之前,完成准備工作
*/
public void doTag() throws JspException
, IOException {
System.out.println(this.num1)
;
System.out.println(this.num2);
// 判斷兩個數據的大小,然后輸出
if (this.num1 > this.num2) {
this.pageContext.getOut().print(num1 +
"大於" + num2);
} else if (this.num1 < this.num2){

this.pageContext.getOut().print(num1 +
"小於" + num2);
}
else{
this.pageContext.getOut().print(num1 +
"等於" + num2);
}

}

@Override
public JspTag getParent() {
// TODO Auto-generated method stub
return null
;
}

@Override
public void setJspBody(JspFragment arg0) {
// TODO Auto-generated method stub

}

@Override
public void setParent(JspTag arg0) {
// TODO Auto-generated method stub

}

}
<taglib xmlns
="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version
="2.1">
<!-- 確定當前標簽庫的版本 -->
<tlib-version>
1.0</tlib-version>
<!-- 建議引入當前便簽庫是,使用的簡寫 @taglib prefix
="my" -->
<short-name>my</short-name>
<!-- 為當前標簽庫配置文件,起一個名稱 * 內容:自定義,全球唯一 -->
<uri>http://www.yxl.cn/jsp/mytag</uri>

<!-- <my:date / > 注冊標簽 -->
<tag>
<!-- 確定標簽名稱 -->
<name>date</name>
<!-- 確定實現類 -->
<tag-class>com.yxl.tag.MyDateTag</tag-class>
<!-- 格式化當前標簽的body內容 * empty:當前標簽沒有標簽體 -->
<body-content>empty</body-content>

</tag>

<!-- <my:maxValue / > 注冊標簽 -->
<tag>
<!-- 確定標簽名稱 -->
<name>maxValue</name>
<!-- 確定實現類 -->
<tag-class>com.yxl.tag.MyMaxValueTag</tag-class>
<!-- 格式化當前標簽的body內容 * empty:當前標簽沒有標簽體 -->
<body-content>empty</body-content>
<!-- 確定當前標簽使用了哪些屬性 -->
<attribute>
<!-- 設置屬性名稱 -->
<name>num1</name>
<!-- 設置屬性是否必須 * true/false * yes/no -->
<required>true</required>
<!-- rtexprvalue 運行時表達式的值 * runtime expression value -->
<rtexprvalue>true</rtexprvalue>
<!-- 確定標簽類型 -->
<type>java.lang.Integer</type>
</attribute>

<attribute>
<!-- 設置屬性名稱 -->
<name>num2</name>
<!-- 設置屬性是否必須 * true/false * yes/no -->
<required>true</required>
<!-- rtexprvalue 運行時表達式的值 * runtime expression value -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>

* 需求:<my:toUpperCase>xxYYdfsdDFwerd</my:toUpperCase>
標簽體
package com.yxl.tag
;

import java.io.IOException
;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspContext
;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;


public class MyToUpperCaseTag implements SimpleTag {

public MyToUpperCaseTag() {
System.out.println(
"默認構造");
}

private PageContext pageContext
;

private JspFragment jspBody
;




/**
*
1、被調用的方法,tomcat調用
*/
public void setJspContext(JspContext pc) {

this.pageContext
= (PageContext) pc;

}

public void setJspBody(JspFragment jspBody){
this.jspBody
= jspBody;
}

/**
*
2、tomcat調用 建議,在doTage方法中完成整個tag的功能 需要再doTage方法之前,完成准備工作
*/
public void doTag() throws JspException
, IOException {
StringWriter stringWriter
= new StringWriter();
this.jspBody.invoke(stringWriter);
String data = stringWriter.toString();
this.pageContext.getOut().print(data.toUpperCase());

}

@Override
public JspTag getParent() {
// TODO Auto-generated method stub
return null
;
}



@Override
public void setParent(JspTag arg0) {
// TODO Auto-generated method stub

}





}
<!-- <my:toUpperCase / > 轉換為大寫 -->
<tag>
<!-- 確定標簽名稱 -->
<name>toUpperCase</name>
<!-- 確定實現類 -->
<tag-class>com.yxl.tag.MyToUpperCaseTag</tag-class>

<!-- 格式化當前標簽的body內容 * empty:當前標簽沒有標簽體 -->
<!-- JSP:支持JSP所有的語法,在Tag中使用
scriptless:對於JSP頁面的腳本不支持
tagdependent:標簽體不做處理,原樣輸出 -->
<body-content>scriptless</body-content>

</tag>
<my:toUpperCase>abcd</my:toUpperCase>
* 需求:循環
使用extends SimpleTagSupport這種方式實現標簽類,SimpleTagSupport已經實現了SimpleTag接口
三種循環遍歷
<taglib xmlns
="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version
="2.1">
<!-- 確定當前標簽庫的版本 -->
<tlib-version>
1.0</tlib-version>
<!-- 建議引入當前便簽庫是,使用的簡寫 @taglib prefix
="my" -->
<short-name>my</short-name>
<!-- 為當前標簽庫配置文件,起一個名稱 * 內容:自定義,全球唯一 -->
<uri>http://www.yxl.cn/jsp/mytag</uri>


<!--
<my:myeach start
="0" end="9" step="1" var="ss">
${ss} ** <br/>
</my:myeach>
-->

<tag>
<name>myeach</name>
<tag-class>com.yxl.tag.MyEachTag</tag-class>
<body-content>scriptless</body-content>

<attribute>
<name>start</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>end</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>step</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>


<!--
<my:myList items
="${listObj}" var="yyyyy">
${yyyyy} ## <br/>
</my:myList>

-->

<tag>
<name>myList</name>
<tag-class>com.yxl.tag.MyListTag</tag-class>
<body-content>scriptless</body-content>

<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>


<tag>
<name>forEach</name>
<tag-class>com.yxl.tag.ForEachTag</tag-class>
<body-content>scriptless</body-content>

<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
package com.yxl.tag
;

import java.io.IOException
;

import javax.servlet.jsp.JspException
;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyEachTag extends SimpleTagSupport{

/*
* <my:myeach start
="0" end="9" step="1" var="ss">
${ss} ** <br/>
</my:myeach>
*/

private Integer start
;
private Integer end;
private Integer step;
private String var;

public void setStart(Integer start) {
this.start
= start;
}

public void setEnd(Integer end) {
this.end
= end;
}

public void setStep(Integer step) {
this.step
= step;
}

public void setVar(String var) {
this.var
= var;
}

public void doTag() throws JspException
, IOException {
//完成功能:將獲得的變量信息,輸出到瀏覽器

for(int i
= start ; i <= end ; i +=step){
//從父類中,獲得pagecontext對象
this.getJspContext().setAttribute(var
, i);
//將el表達式的結果發送到瀏覽器
// * el表達式的位置
// * 如何發送
this.getJspBody().invoke(null)
;
//this.getJspBody().invoke(this.getJspContext().getOut());
}

}




}




package com.yxl.tag
;

import java.io.IOException
;
import java.util.Iterator;
import java.util.List;

import javax.servlet.jsp.JspException
;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyListTag extends SimpleTagSupport {

/*
<my:myList items
="${listObj}" var="yyyyy">
${yyyyy} ## <br/>
</my:myList>
*/

private List items
;
private String var;
public void setItems(List items) {
this.items
= items;
}

public void setVar(String var) {
this.var
= var;
}

@Override
public void doTag() throws JspException
, IOException {
//完成功能:將獲得的list信息遍歷輸出到瀏覽器
Iterator it
= items.iterator();
while(it.hasNext()){
Object str
= it.next();
//將結果放置到作用域
this.getJspContext().setAttribute(var
, str);
//將el表達式的結果數據到瀏覽器
this.getJspBody().invoke(null)
;
}
}



}



package com.yxl.tag
;

import java.io.IOException
;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException
;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class ForEachTag extends SimpleTagSupport {

/*
<my:myList items
="${listObj}" var="yyyyy">
${yyyyy} ## <br/>
</my:myList>
*/

private Iterator<Object> items
;
private String var;
public void setItems(Object items) {
//list
if(items instanceof List){
this.items
= ((List)items).iterator();
}
//map
if(items instanceof Map){
this.items
= ((Map)items).entrySet().iterator();
}
//object
[]
if(items instanceof Object
[]){
this.items
= Arrays.asList((Object[])items).iterator();
}

}

public void setVar(String var) {
this.var
= var;
}

@Override
public void doTag() throws JspException
, IOException {
//完成功能:將獲得的list信息遍歷輸出到瀏覽器

while(items.hasNext()){
Object str
= items.next();
//將結果放置到作用域
this.getJspContext().setAttribute(var
, str);
//將el表達式的結果數據到瀏覽器
this.getJspBody().invoke(null)
;
}
}



}


<my:myeach start
="0" end="9" step="1" var="eeee">
${eeee} ** <br/>
</my:myeach>
<%

List<String> list
= new ArrayList<String>();
list.add("abc");
list.add("123");
list.add("wasd");

pageContext.setAttribute(
"listObj",list);
%>
myList<br/>
<my:myList items
="${listObj}" var="yyyyy">
${yyyyy} ## <br/>
</my:myList>

<my:forEach items
="${listObj}" var="mm">
${mm} <br/>
</my:forEach>

<hr/>

<%

Map<String
,String> map = new HashMap<String,String>();
map.put("11111","11111");
map.put("22222","222222");
map.put("33333","33333");

pageContext.setAttribute(
"mapObj",map);

%>
遍歷Map<br/>

<my:forEach items
="${mapObj}" var="map">
${map.key} ---- ${map.value} <br/>
</my:forEach>
三、自定義函數
* 創建類,但方法必須是靜態的
package com.yxl.domain
;

public class Calculator {
private String firstNum
;
private String operator;
private String secondNum;
private String result;
public String getFirstNum() {
return firstNum
;
}
public void setFirstNum(String firstNum) {
this.firstNum
= firstNum;
}
public String getOperator() {
return operator
;
}
public void setOperator(String operator) {
this.operator
= operator;
}
public String getSecondNum() {
return secondNum
;
}
public void setSecondNum(String secondNum) {
this.secondNum
= secondNum;
}
public String getResult() {
return result
;
}
public void setResult(String result) {
this.result
= result;
}
public Calculator() {
}

//計算方法
public static void calculator(Calculator cal){

//通過運算符,將firstNum和secondNum處理的結果,存放到result



double first
= Double.valueOf(cal.firstNum);
double second = Double.valueOf(cal.secondNum);
char ope = cal.operator.charAt(0);

switch (ope) {
case '+':
cal.result
= String.valueOf(first + second);
break;
case '-':
cal.result
= String.valueOf(first - second);
break;
case '*':
cal.result
= String.valueOf(first * second);

break
;
case '/':
cal.result
= String.valueOf(first / second);
break;

default:
throw new RuntimeException(
"非法操作符");
}

}
}

* 書寫配置文件tld
新建myFun.tld
<?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">

<tlib-version>
1.0</tlib-version>
<short-name>myfn</short-name>
<uri>http://www.yxl.cn/mytag/functions</uri>
<!-- 確定當前函數 myfn:calculator(cal) -->
<function>
<name>calculator</name>
<function-class>com.yxl.domain.Calculator</function-class>
<!-- 當前使用函數的聲明 public static void calculator(Calculator cal) -->
<function-signature>void calculator(com.yxl.domain.Calculator)</function-signature>
</function>

</taglib>
* 引用
* <%@ taglib uri
="http://www.yxl.cn/mytag/functions" prefix="myFn" %>
* 測試
<jsp:useBean id
="cal" class="com.yxl.domain.Calculator"></jsp:useBean>
<jsp:setProperty property
="firstNum" value="1" name="cal"/>
<jsp:setProperty property
="operator" value="+" name="cal"/>
<jsp:setProperty property
="secondNum" value="4" name="cal"/>
${myFn:calculator(cal)}
${cal.result}
四、總結
* 共同點:
* 需要引入
* <%@ taglib uri
="http://www.yxl.cn/mytag/myeach" prefix="my" %>
* 都需要配置tld文件
* 區別:
* 自定義標簽
* 創建一個類,完成一個功能或一組功能。
* 可以選擇el表達式
* 自定義函數
* 創建一個靜態方法,完成一個操作。
* 必須與EL表達式結合使用
${fn:xxxx}

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com