自定义标签:
jsp中自定义标签使用形式
代码:
1<itcast:showtime/>
itcast 为标签的名字,即tld配置文件的名称
showtime为tld配置文件中tag标签中的name值
2书写java类:
public class ShowTime extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
Date now=new Date();
PageContext pc=(PageContext)getJspContext(); //继承SimpleTagSupport的类中有jspContext的对象,这里强转成pagecontext的对象
pc.getOut().write(now.toLocaleString());
}
}
java类需要实现simpleTag接口,我们一把继承SimpleTagSupport类
覆盖doTag方法
java类中封装需要执行的java代码即可
3书写配置文件 tld文件
<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>itcast</short-name> //name和uri只是和jsp建立联系,并没有实际意义
<uri>www.itcast.cn</uri>
<tag>
<name>showtime</name> //标签的方法名
<tag-class>text.jsp.ShowTime</tag-class> //java类的全名
<body-content>empty</body-content> //开始标签和结束标签有没有内容
</tag>
</taglib>
simpleTag接口中的方法:
void doTag():由服务器调用。在JSP中遇到标签时调用。
JspTag getParent():由程序员调用。获取该标签的父标签对象。没有返回null
以下三个方法的共同特点:由服务器调用,在调用doTag之前就调完了。
void setJspBody(JspFragment jspBody):由服务器调用。传入标签的内容。
void setJspContext(JspContext pc):由服务器调用。传入当前页面的pageContext对象
void setParent(JspTag parent):由服务器调用。传入你的爹。没爹传入null
标签的实际作用:
获得主体内容并输出:
JspFragment jf=getJspBody();
jf.invoke(null);
简易写法:
getJspBody().invoke(null);
1 使得主体内容不显示
<body-content>scriptless</body-content>//主体内容为非脚本
2控制结束标签后的内容不执行
throw new SkipPageException();
3控制主体内容重复运行
在类中写入循环代码即可
循环输出主体内容代码体现:
jsp:<itcast:ShowFor count="5">saq</itcast:ShowFor> //count为标签属性
itcast.tld:
<tag>
<name>ShowFor</name>
<tag-class>text.jsp.ShowFor</tag-class>
<body-content>scriptless</body-content>
//配置属性
<attribute>
<name>count</name>//属性名
<required>true</required>//是否必须输入属性值
<rtexprvalue>true</rtexprvalue>//是否支持表达式
</attribute>
</tag>
类:
public class ShowFor extends SimpleTagSupport {
private int count;
public void setCount(int count) {
this.count = count;
}
public void doTag() throws JspException, IOException {
for(int i=0;i<count;i++){
getJspBody().invoke(null);//输出主体内容,当为null时,就输出主体内容
}
}
}
4获取主体内容,并操作主体内容后输出
public void doTag() throws JspException, IOException {
//获取主体内容
JspFragment jf=getJspBody();
//将主体内容写入字符缓存
StringWriter sw=new StringWriter();
jf.invoke(sw);
//调用string的大写转换方法
String jfString=sw.getBuffer().toString();
jfString=jfString.toUpperCase();
//输出
PageContext pc=(PageContext) getJspContext();
pc.getOut().write(jfString);
}
body-content中的内容:
1 jsp 不考虑,传统标签处理类中
2 empty 传统标签和普通标签都能用,主体中不能有内容
3 scriptless 简单标签使用,要求主体中有内容,但不能有“<”“%”,可以有EL表达式,但不能有java表达式
4 tagdependent 简单标签使用,告诉类,主体标签中的为文本
实现if功能的标签:
类:
public class IfSimpleTag extends SimpleTagSupport{
private Boolean test;
public void setTest(Boolean test) {
this.test = test;
}
public void doTag() throws JspException, IOException {
if(test){
getJspBody().invoke(null);
}
}
}
jsp:
<%session.setAttribute("user", "djw");%>
<itcast:if test="${SessionScope.user==null}">
<a href="#">登录</a>
</itcast:if>
<itcast:if test="${SessionScope.user!=null }">
<a href="#">注销</a>
</itcast:if>
实现ifelse功能:
jsp:
<%pageContext.setAttribute("gender", "man");%>
<itcast:choose>
<itcast:when test="${gender=='man'}">
男性
</itcast:when>
<itcast:else>
女性
</itcast:else>
</itcast:choose>
父标签类:
public class ChooseSimpleTage extends SimpleTagSupport {
private Boolean flag=true;
public Boolean getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
public void doTag() throws JspException, IOException {
getJspBody().invoke(null);
}
}
when类:
public class WhenSimpleTage extends SimpleTagSupport{
private boolean test;
public void setTest(boolean test) {
this.test = test;
}
public void doTag() throws JspException, IOException {
if(test){
getJspBody().invoke(null);
ChooseSimpleTage cst=(ChooseSimpleTage) getParent();
cst.setFlag(false);
}
}
}
else类:
public class ElseSimpleTage extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
ChooseSimpleTage cst=(ChooseSimpleTage) getParent();
if(cst.getFlag()){
getJspBody().invoke(null);
}
}
}
for循环标签(简易)
jsp:
<body>
<%
List list=new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
pageContext.setAttribute("list", list);
%>
<itcast:for items="${list}" var="s">
${s}<br/>
</itcast:for>
</body>
处理类:
private List items;
private String var;
public void setItems(List items) {
this.items = items;
}
public void setVar(String var) {
this.var = var;
}
public void doTag() throws JspException, IOException {
PageContext pc=(PageContext) getJspContext();
if(items!=null){
for(Object obj:items){
pc.setAttribute(var, obj);
getJspBody().invoke(null);
}
}
}
for循环增强版:
jsp:
<%
Map map=new HashMap();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c", "ccc");
pageContext.setAttribute("map", map);
%>
<itcast:for2 items="${map.}" var="me">
${me.key}=${me.value}<br/>
</itcast:for2>
处理类:
public class ForSimpleTage2 extends SimpleTagSupport {
private Object items;
private String var;
private Collection collection=new ArrayList();
public void setItems(Object items) {
if(items instanceof List){
collection=(Collection) items;
}else if(items instanceof Map){
collection=((Map) items).entrySet();
}else if(items.getClass().isArray()){
//基本类型数组不属于Object[],属于基本类型的数组,
这里的处理方式一并处理了基本类型数组和Object[]类型的数组
int len=Array.getLength(items);
for(int i=0;i<len;i++){
collection.add(Array.get(items, i));
}
}
}
public void setVar(String var) {
this.var = var;
}
public void doTag() throws JspException, IOException {
PageContext pc=(PageContext) getJspContext();
for(Object obj:collection){
pc.setAttribute(var, obj);
getJspBody().invoke(null);
}
}
}
实现html转义的标签:
jsp代码:
<%
pageContext.setAttribute("s", "<hr/>");
%>
<itcast:filter>
${s}
</itcast:filter>
处理类代码:
public class Filter extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
StringWriter sw=new StringWriter();
getJspBody().invoke(sw);
String str=sw.getBuffer().toString();
String new_str=filter(str);
getJspContext().getOut().write(new_str);
}
private String filter(String message) {
if (message == null)
return (null);
char content[] = new char[message.length()];
message.getChars(0, message.length(), content, 0);
StringBuilder result = new StringBuilder(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '&':
result.append("&");
break;
case '"':
result.append(""");
break;
default:
result.append(content[i]);
}
}
return (result.toString());
}
}
其中filter方法在tomcat中有例子代码,复制即可
导入标签库:<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
jsptlcore核心标签:
1 out:
<%
pageContext.setAttribute("s", "<hr/>");
%>
<c:out value="${s}" default="输入错误" escapeXml="true"></c:out>
default:输入的对象无法找到时输出的值
escapeXml:自动转义html符号,默认值为true
2 set标签:
<c:set value="上海" var="s" scope="page"></c:set>
3 设置javabean的属性:
<jsp:useBean id="person" class="jsp.core.Person"></jsp:useBean>
<c:set property="name" target="${person }" value="djw"></c:set>
${person.name}
4设置map的值:
<%
Map map=new HashMap();
map.put("a", "aaa");
pageContext.setAttribute("map", map);
%>
<c:set property="b" value="bbb" target="${map }"></c:set>
${map.a}<br/>
${map.b }
5从指定域中删除数据
<c:set var="s1" value="pp" scope="page"></c:set>
<c:remove var="s1" scope="page"/>
入股scope不设置,则为所有域范围
6 除咯i异常:
<c:catch>
</c:catch>
7 循环遍历:
<c:forEach items="" begin="" end="" step=""> 需要遍历的内容</c:forEach>
items:需要遍历的对象
begin:起始索引
end:结束索引
step: 遍历间隔 默认为1
foreach 遍历集合数组和表格集合:
<%
List<Person> list=new ArrayList<Person>();
list.add(new Person("djw","男","上海"));
list.add(new Person("www","男","北京"));
pageContext.setAttribute("p", list);
%>
<table border="1">
<tr>
<th>姓名</th>
<th>性别</th>
<th>城市</th>
</tr>
<c:forEach items="${p}" var="fp" varStatus="vs">
//varStatus是指向一个对象,该对象记录着当前元素的一些信息
//int getIndex 元素的索引
//int getCount 元素的位数
//boolean isFirst 是否是第一个元素
//boolean isLast 是否为最后一个元素
<tr>
<td>
${fp.name}
</td>
<td>
${fp.gender}
</td>
<td>
${fp.city}
</td>
</tr>
</c:forEach>
</table>
8 遍历字符串标签:
<%
pageContext.setAttribute("s", "2014-06-11");
%>
<c:forTokens items="${s }" delims="-" var="p">
${p}<br/>
</c:forTokens>
9 包含标签:
</c:forTokens>
<c:import url="/3.jsp"></c:import> 包含本应用中的地址
<c:import url="http://www.baidu.com"></c:import> 包含外部地址
10转发:
<c:redirect url="/3.jsp"></c:redirect>
11 url(这里完成了中文参数的编码和url的重写)
<c:url value="/3.jsp" var="url"></c:url>
<c:param name="username" value="djw"></c:param>
//上面语句相当调用了(
<%
pageContext.setAttribute("url", request.getContextPath()+"/3.jsp");
%>)这个语句
<a href="url"></a>