自定義標簽庫開發與el表達式


自定義標簽庫開發與el表達式

 

1.自定義標簽庫的開發
自定義標簽庫主要用於移除jsp頁面中的java 代碼。

步驟一:
編寫一個實現Tag接口的類(建議繼承TagSupport),把java代碼一直到這個類中。


package cn.soldier.tag;

import java.io.IOException;

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

public class viewIP extends TagSupport {

private static final long serialVersionUID = 1L;

@Override
public int doStartTag() throws JspException {
String _ip = pageContext.getRequest().getLocalAddr();
try {
pageContext.getOut().write(_ip);
} catch (IOException e) {
throw new RuntimeException();
}
return super.doStartTag();
}

}


步驟二:
在web-inf文件下編寫tld文件,在tld文件中把標簽處理器類描述成一個標簽。


<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>soldier</short-name>
<uri>/soldier</uri>
<tag>
<name>viewIP</name>
<tag-class>cn.soldier.tag.viewIP</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>

步驟三:使用
<%@ taglib uri="/soldier" prefix="soldier"%>

<soldier:viewIP />


自定義標簽的實現原理:

ie web服務器 1.jsp viewTag

當瀏覽器向服務器請求jsp頁面,服務器解釋到自定義標簽時,
1.首先實例化對應的標簽處理器類。
2.調用setPageContext方法,把頁面的將pageContext對象傳遞給標簽處理器類
3.判斷標簽是否有父標簽,如果有,則將父標簽作為一個對象,通過setParent()方法傳遞給標簽處理器類。沒有傳null
4.完成以上標簽處理器類初始化好了。服務器開始執行標簽,這時遇到標簽的開始標簽,就調用doStarTag方法。
5.如果標簽有標簽體,服務器一般會執行標簽體
6.服務器遇到標簽的結束標簽,則執行doEndTag方法。
7.整個標簽執行完后,服務器一般會調用release()方法。釋放標簽工作時占用的資源。
8.服務器接着執行標簽后面的內容。

tag標簽的5個功能 v1.0:
1.移植java代碼
@Override
public int doStartTag() throws JspException {
String _ip = pageContext.getRequest().getLocalAddr();
try {
pageContext.getOut().write(_ip);
} catch (IOException e) {
throw new RuntimeException();
}
return super.doStartTag();
}
2.控制jsp頁面部分內容是否執行
public class Tagdemo1 extends TagSupport {
@Override
public int doStartTag() throws JspException {
//用法,控制標簽體內容是否執行
return Tag.EVAL_BODY_INCLUDE;// 返回結果為這個時,會執行標簽體的內容
// return Tag.SKIP_BODY//返回結果給這個時,不會執行標簽體內容。
}
}
3.控制整個jsp頁面是否執行
public class Tagdemo2 extends TagSupport {
@Override
public int doEndTag() throws JspException {
// return Tag.SKIP_PAGE;// 標簽體后面內容不會被執行
return Tag.EVAL_PAGE;// 標簽體后面內容keyi 被執行
}
@Override
public int doStartTag() throws JspException {
return Tag.EVAL_BODY_INCLUDE;
}
}
4.控制jsp頁面內容的重復執行
public class Tagdemo3 extends TagSupport {
int x = 3;
@Override
public int doStartTag() throws JspException {
return Tag.EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
x--;
if (x > 0) {
return IterationTag.EVAL_BODY_AGAIN; //標簽體內容繼續執行
} else {
return IterationTag.SKIP_BODY;//標簽體內容跳過,即結束執行
}
}
}
5.修改jsp頁面內容輸出
public class Tagdemo4 extends BodyTagSupport {
@Override
public int doStartTag() throws JspException {
return BodyTag.EVAL_BODY_BUFFERED;//把標簽體封裝到對象,可以通過getBodyContent()方法去除
}
@Override
public int doEndTag() throws JspException {
BodyContent bc = this.getBodyContent();//得到標簽體內容
String content = bc.toString();
content =content.toUpperCase();//變為大寫
try {
this.pageContext.getOut().write(content);
} catch (IOException e) {
e.printStackTrace();
}
return Tag.EVAL_PAGE;// 標簽體后面內容可以被執行
}
}


tag標簽的5個功能 v2.0:
1.移植java代碼

2.控制jsp頁面部分內容是否執行
public class Tagdemo1 extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody(); // fragment 片段
jf.invoke(this.getJspContext().getOut());// 執行標簽體 //invoke調用
//如果不讓輸出,就不執行上面的代碼就行了。
}
}
3.控制整個jsp頁面是否執行
public class Tagdemo4 extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
throw new SkipPageException();// 拋出異常后余下的jsp不再執行
}
}
4.控制jsp頁面內容的重復執行
public class Tagdemo2 extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody(); // fragment 片段
for (int i = 0; i < 3; i++) {
jf.invoke(this.getJspContext().getOut());// 執行標簽體 //invoke調用
}
}
}
5.修改jsp頁面內容輸出
public class Tagdemo3 extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody(); // fragment 片段
// 這里invoke接受一個writer,但是目的是獲取標簽體的內容,所以應該找一個有緩沖區的writer,且該writer能夠返回緩沖區內容。
StringWriter sw = new StringWriter();
jf.invoke(sw);
//
String conter = sw.toString();// 這里拿到標簽體內容了。
this.getJspContext().getOut().write(conter.toUpperCase());// 修改標簽體內容
}
}


簡單標簽的實現原理:

ie web服務器 1.jsp viewTag

當瀏覽器向服務器請求jsp頁面,服務器解釋到自定義標簽時,
1.首先實例化對應的標簽處理器類。
2.調用setJspContext方法,把頁面的將pageContext對象傳遞給標簽處理器類
3.調用setParent()方法,把父標簽傳遞給標簽處理器類
4.調用setJspBody方法,把封裝好的JspFragment對象傳遞給標簽處理器類。
5.完成以上標簽處理器類初始化好了。服務器開始執行doEndTag方法。
6.標簽執行完后,釋放標簽工作時占用的資源。
7.服務器接着執行標簽后面的內容。

標簽帶屬性
public class Tagdemo5 extends SimpleTagSupport {
private int count;
// 標簽帶屬性
@Override
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody();
for (int i = 0; i < count; i++) {
jf.invoke(this.getJspContext().getOut());
}
}
public void setCount(int count) {
this.count = count;
}
}
tld配置如下:
<tag>
<name>demo5</name>
<tag-class>cn.soldier.SimpleTag.Tagdemo5</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>count</name>
<required>true</required>//是否必須標識此屬性
<rtexprvalue>true</rtexprvalue>//是否允許表達式
</attribute>
</tag>

防盜鏈標簽
public class Tagdemo6 extends SimpleTagSupport {
private String site;
private String page;

// 標簽帶屬性
@Override
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) this.getJspContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
String referer = request.getHeader("referer");

if (referer == null || !referer.startsWith(site)) {

if (page.startsWith(request.getContextPath())) {
response.sendRedirect(page);
} else if (page.startsWith("/")) {
response.sendRedirect(request.getContextPath() + page);
} else {
System.out.println(request.getContextPath() + "/" + page);
response.sendRedirect(request.getContextPath() + "/" + page);
}
throw new SkipPageException();
}

}

public void setSite(String site) {
this.site = site;
}

public void setPage(String page) {
this.page = page;
}

}

<tag>
<name>demo6</name>
<tag-class>cn.soldier.SimpleTag.Tagdemo6</tag-class>
<body-content>empty</body-content>
<attribute>
<name>site</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>page</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

<SimpleTagSoldier:demo6 page="message.jsp" site="http://localhost:8080/" />

if標簽
private boolean test;
@Override
public void doTag() throws JspException, IOException {
if(test)
this.getJspBody().invoke(null);//執行,因為不帶標簽體所以沒有不用輸出標簽體
}

public void setTest(boolean test) {
this.test = test;
}
<tag>
<name>demo7</name>
<tag-class>cn.soldier.SimpleTag.Tagdemo7</tag-class>
<body-content>empty</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

 

if-else標簽


public class chooseTag extends SimpleTagSupport {
private boolean isDo;

// 標簽帶屬性,這里省略setter
@Override
public void doTag() throws JspException, IOException {
this.getJspBody().invoke(null);
}

public boolean isDo() {
return isDo;
}

public void setDo(boolean isDo) {
this.isDo = isDo;
}
}

public class WhenTag extends SimpleTagSupport {
private boolean test;

@Override
public void doTag() throws JspException, IOException {
ChooseTag parent = (ChooseTag) this.getParent();
if (test && !parent.isDo()) {
this.getJspBody().invoke(null);
parent.setDo(true);
}
}

public void setTest(boolean test) {
this.test = test;
}
}

public class OtherWiseTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
ChooseTag parent = (ChooseTag) this.getParent();
if (!parent.isDo()) {
this.getJspBody().invoke(null);
parent.setDo(true);
}
}
}

<tag>
<name>choose</name>
<tag-class>cn.soldier.SimpleTag.example.ChooseTag</tag-class>
<body-content>scriptless</body-content>
</tag>
<tag>
<name>when</name>
<tag-class>cn.soldier.SimpleTag.example.WhenTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>otherWise</name>
<tag-class>cn.soldier.SimpleTag.example.OtherWiseTag</tag-class>
<body-content>scriptless</body-content>
</tag>

<sold:choose>
<sold:when test="true">aaa</sold:when>
<sold:otherWise>bbb</sold:otherWise>
</sold:choose>


迭代標簽

html轉發標簽


如何打包開發的自定義標簽


el中的作用域

el中的作用域 對應關系
*pageContext 當前頁的pageContext對象
*pageScope 把page作用域中的數據映射為一個map對象
*requestScope 把request作用域中的數據映射為一個map對象
*sessionScope 把session作用域中的數據映射為一個map對象
*applicationScope 把application作用域中的數據映射為一個map對象
*param 對應request.getParameter()
paramValues 對應request.getParameterValues()
header 對應request.getHeader()
headerValues 對應request.getHeaderValues()
cookie 對應request.getCookies()
initParam 對應ServletContext.getInitParamter()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM