JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库。
JSTL 核心标签库标签共有13个,功能上分为4类:
1.表达式控制标签:out、set、remove、catch
2.流程控制标签:if、choose、when、otherwise
3.循环标签:forEach、forTokens
4.URL操作标签:import、url、redirect
使用时需要在项目中加入jstl-1.2.jar,同时在jsp中加入以下代码来使用
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
只使用 核心标签库标签中的标签是不能满足需求的,常常会需要自定义标签。
一、新建.tld文件
.tld文件需要放在WEB-INF的tld文件夹下,没有则需要新建。否则tomcat读不到
<?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>这个标签是指定我们定义标签的简称,这个作用不大 -->
<short-name>t</short-name>
<!-- <uri>是给这个标签文件指定一个访问路径,这个路径我们在Jsp页面中引入这个标签的时候需要用到 ,如:<%@ taglib prefix="t"
uri="/mytags"%> -->
<uri>/mytags</uri>
<display-name>"自定义标签"</display-name>
<!-- 菜单生成控件 -->
<tag>
<name>menu</name>
<!-- <tag-class>这个标签就是指定我们自定义的标签类的全称 -->
<tag-class>com.zhs.tag.MenuTag</tag-class>
<!-- <body-content>这个标签表明自定义标签是否有标签体内容(empty:没有,JSP:有) -->
<body-content>JSP</body-content>
<display-name>左侧菜单生成控件</display-name>
<small-icon>111</small-icon>
<description>左侧菜单生成控件可选样式easyui,bootstrap,json</description>
<!-- 参数,后台可根据name属性取出值 -->
<attribute>
<name>menuFun</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>菜单信息</description>
</attribute>
<attribute>
<name>style</name>
<rtexprvalue>true</rtexprvalue>
<description>菜单样式</description>
</attribute>
</tag>
</taglib>
二、新建java类处理标签中的数据(可将数据装换成任何需要的样式)
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import com.zhs.model.TSFunction;
/**
*
* 类描述:菜单标签*/
public class MenuTag extends TagSupport {
private static final long serialVersionUID = 1L;
protected String style = "easyui";// 菜单样式
protected List<Map> menuFun;// 一级菜单
// 1、public void setPageContext(PageContext pc),
// JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。
// 2、public void setParent(Tag
// t),setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。
// 3、public int
// doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
// 4、public int
// doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。
// 5、public void
// release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。
@Override
public int doStartTag() throws JspTagException {
// 返回值类型:
// SKIP_BODY(=0) :跳过了开始和结束标签之间的代码。
// EVAL_BODY_INCLUDE(=1):将body的内容输出到存在的输出流中
// SKIP_PAGE(=5) : 忽略剩下的页面。
// EVAL_PAGE(=6):继续执行下面的页
return EVAL_PAGE;
}
@Override
public int doEndTag() throws JspTagException {
try {
JspWriter out = this.pageContext.getOut();
String menu = (String) this.pageContext.getSession().getAttribute(
"leftMenuCache" + style);
if (menu != null) {
//向页面转发数据(本例中为列表)
out.print(menu);
} else {
menu = end().toString();
this.pageContext.getSession().setAttribute(
"leftMenuCache" + style, menu);
out.print(menu);
}
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_PAGE;
}
public StringBuffer end() {
StringBuffer sb = new StringBuffer();
sb.append(getAceMultistageTree(menuFun));
return sb;
}
//获取til文件中的值
public void setStyle(String style) {
this.style = style;
}
public void setMenuFun(List<Map> menuFun) {
this.menuFun = menuFun;
}
//处理数据
public static String getAceMultistageTree(List<Map> list) {
StringBuffer menuString = new StringBuffer();
int curIndex = 0;
for (Map map : list) {
TSFunction parent=(TSFunction)map.get("parentfunction");
List<TSFunction> childList=(List<TSFunction>)map.get("childfunction");
if(childList==null){
menuString.append("<li class='active'>"
+"<a href='index.html'>"
+"<i class='menu-icon fa fa-tachometer'></i>"
+"<span class='menu-text'> "
+parent.getFunctionName()
+" </span>"
+"</a>"
+"<b class='arrow'></b>"
+"</li>");
}else{
menuString.append("<li class=''>"
+"<a href='#' class='dropdown-toggle'>"
+"<i class='menu-icon fa fa-leaf green'></i>"
+"<span class='menu-text'> "
+parent.getFunctionName()
+" </span>"
+"<b class='arrow fa fa-angle-down'></b>"
+"</a>"
+"<b class='arrow'></b>"
+"<ul class='submenu'>");
for(TSFunction child:childList){
menuString.append("<li class=''>"
+"<a href=\"javascript:loadModule('"
+child.getFunctionName()
+"','/cssiot"
+child.getFunctionUrl()
+"')\">"
+"<i class='menu-icon fa fa-caret-right'></i>"
+child.getFunctionName()
+"</a>"
+"<b class='arrow'></b>"
+"</li>");
}
menuString.append("</ul></li>");
}
}
return menuString.toString();
}
}
注:
TagSupport 对象可以引用tomcat中的jsp-api.jar与servlet-api.jar
三、在jsp页面中使用
<t:menu menuFun="${menuMap}" style="ace" ></t:menu>
使用时可向后台传递参数,整个过程(tld文件,jsp文件,java文件)中参数名要保持一致
附录:
程序用的实体类
import java.util.List;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* 菜单权限表
*
*/
@Entity
@Table(name = "t_s_function")
@org.hibernate.annotations.Proxy(lazy = false)
public class TSFunction extends BaseEntity {
private TSFunction TSFunction;// 父菜单
private String functionName;// 菜单名称
private Short functionLevel;// 菜单等级
private String functionUrl;// 菜单地址
private String functionOrder;// 菜单排序
private String iconId;// 图标id
public boolean hasSubFunction(Map<Integer, List<TSFunction>> map) {
if (map.containsKey(this.getFunctionLevel() + 1)) {
return hasSubFunction(map.get(this.getFunctionLevel() + 1));
}
return false;
}
public boolean hasSubFunction(List<TSFunction> functions) {
for (TSFunction f : functions) {
if (f.getTSFunction().getId().equals(this.getId())) {
return true;
}
}
return false;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "parentfunctionid")
public TSFunction getTSFunction() {
return this.TSFunction;
}
public void setTSFunction(TSFunction TSFunction) {
this.TSFunction = TSFunction;
}
@Column(name = "functionname", nullable = false, length = 50)
public String getFunctionName() {
return this.functionName;
}
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
@Column(name = "functionlevel")
public Short getFunctionLevel() {
return this.functionLevel;
}
public void setFunctionLevel(Short functionLevel) {
this.functionLevel = functionLevel;
}
@Column(name = "functionurl", length = 100)
public String getFunctionUrl() {
return this.functionUrl;
}
public void setFunctionUrl(String functionUrl) {
this.functionUrl = functionUrl;
}
@Column(name = "functionorder")
public String getFunctionOrder() {
return functionOrder;
}
public void setFunctionOrder(String functionOrder) {
this.functionOrder = functionOrder;
}
public String getIconId() {
return iconId;
}
public void setIconId(String iconId) {
this.iconId = iconId;
}
}