自定义标签库开发与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()

 posted on 2014-10-23 23:45  编程小兵  阅读(4080)  评论(0编辑  收藏  举报