我们的开发方式是由demo人员完成系统的静态页面,并通过css进行美化。
为最大可能利用美工完成的静态页面,我们需要尽量减少对原html的冲击,因此我首先想到的Freemarker。
但是Freemarker最终让我空喜一场,最终自定义了一个可以递归嵌套的jsp tag来达到这个目的。
下面是解决这个问题的过程:
用css模版sdmenu来实现系统菜单,静态html如下格式:
<div style="float: left" id="my_menu" class="sdmenu">
<div>
<span>Email Template</span>
<a href="#" target="mainFrame">Welcome Notes</a>
<a href="#" target="mainFrame">Deposit Reminder</a>
<a href="#" target="mainFrame">Final Payment</a>
<a href="#" target="mainFrame">Recommendation Message</a>
</div>
<div>
<span>Parameter Manage</span>
<a href="#" target="mainFrame">List all parameters</a>
</div>
……
</div>
开始准备用Freemarker来搞定,设计Freemarker模版格式为:(定义desc是x对象下面个一个list属性)
<#list listObj as x>
x
<#list ${x.desc} as y>
y
</#list>
</#list>
原来担心<#list>,不能支持嵌套,结果用1..count的循环方式,发现完全可以嵌套循环,暗喜。
但是很快,不幸的事情还是出现了,Freemarker不支持<#list ${x.desc} as y>这样写。
一时愤怒,准备改写Freemarker,但是想想改了,也不知道怎么提交到Freemarker项目中。
还是不做那根葱算了。
纠结之后,决定自定义tag来解决这个问题。
先设计tag的写法
<ui:list listName="list" scope="request">
<div>
<span>__menuName__</span>
<ui:list listName="sublist" scope="parent">
<a href="__url__" target="__target__">__menuName__</a>
</ui:list>
</div>
</ui:list>
然后写一个jsp测试页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.math.*,java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="/WEB-INF/ui.tld" prefix="ui" %>
<%
List list = new ArrayList();
List subList = new ArrayList();
subList.add("sub1");
subList.add("sub2");
subList.add("sub3");
Map m = new HashMap();
m.put("id", "111");
m.put("label", " 这也是中文 ");
m.put("name", " 这也是中文 ");
m.put("value", " 这也是中文 ");
m.put("checked", "");
m.put("subList", subList);
list.add(m);
list.add(m);
list.add(m);
list.add(m);
list.add(m);
list.add(m);
list.add(m);
request.setAttribute("testlist",list);
%>
<html>
<head>
</head>
<body>
<ui:list listName="testlist">
<br/>hello __idx__ !!! __name__<br/>
<ui:list listName="subList" scope="parent">
morning __idx__ !!!<br/>
</ui:list>
</ui:list>
</body>
</html>
最后,完成Tag类的编写。
public class ListTag extends BodyTagSupport {
private Iterator iter = null;
private int index = 0;
private String listName = null;
private String scope = null;
private Object currentObj = null;
private int index = 0;
private String listName = null;
private String scope = null;
private Object currentObj = null;
public ListTag() {
super();
}
super();
}
public int doStartTag() throws JspException {
index = 0;
System.out.println("doStartTag = " + this.getBodyContent());
try {
List list = null;
ListTag parent =(ListTag)getParent();
if (parent != null && "parent".equals(this.scope)){
Object curObj = parent.getCurrentObj();
if (curObj == null){
return SKIP_BODY;
}
if (curObj instanceof Map){
Map m = (Map) curObj;
list = (List)m.get(listName);
}else{
list = (List)PropertyUtils.getProperty(curObj, listName);
}
}else{
list = (List) this.pageContext.getRequest().getAttribute(listName);
}
index = 0;
System.out.println("doStartTag = " + this.getBodyContent());
try {
List list = null;
ListTag parent =(ListTag)getParent();
if (parent != null && "parent".equals(this.scope)){
Object curObj = parent.getCurrentObj();
if (curObj == null){
return SKIP_BODY;
}
if (curObj instanceof Map){
Map m = (Map) curObj;
list = (List)m.get(listName);
}else{
list = (List)PropertyUtils.getProperty(curObj, listName);
}
}else{
list = (List) this.pageContext.getRequest().getAttribute(listName);
}
if (list == null || list.size() == 0) {
return SKIP_BODY;
}
return SKIP_BODY;
}
iter = list.iterator();
if (iter.hasNext()){
this.currentObj = iter.next();
}else{
this.currentObj = null;
}
} catch (Exception ex) {
ex.printStackTrace();
throw new JspException("IO problems during ListTag's doStartTag "
+ ex.getMessage());
}
return EVAL_BODY_BUFFERED;
//return EVAL_BODY_INCLUDE 直接顯示jsp中內容。
}
if (iter.hasNext()){
this.currentObj = iter.next();
}else{
this.currentObj = null;
}
} catch (Exception ex) {
ex.printStackTrace();
throw new JspException("IO problems during ListTag's doStartTag "
+ ex.getMessage());
}
return EVAL_BODY_BUFFERED;
//return EVAL_BODY_INCLUDE 直接顯示jsp中內容。
}
public int doAfterBody() throws JspException {
try {
try {
String tagString = this.getBodyContent().getString();
if (this.currentObj != null) {
Map m = new HashMap();
if (currentObj instanceof Map){
m = (Map) currentObj;
}else{
m = BeanUtils.describe(currentObj);
}
if (this.currentObj != null) {
Map m = new HashMap();
if (currentObj instanceof Map){
m = (Map) currentObj;
}else{
m = BeanUtils.describe(currentObj);
}
String regEx = "__idx__";
tagString = tagString.replaceAll(regEx, String.valueOf(index));
tagString = tagString.replaceAll(regEx, String.valueOf(index));
Iterator mIter = m.keySet().iterator();
while (mIter.hasNext()) {
String key = (String) mIter.next();
//String value = (String) m.get(key);
Object value = PropertyUtils.getProperty(currentObj, key);
if (value instanceof Date) {
value = CommonUtil.date2String((Date) value,
CommonUtil.DATE_FORMAT);
}
value = Constant.transfer(key,value);
key = "__" + key + "__";
value = value == null ? "" : value;
String key = (String) mIter.next();
//String value = (String) m.get(key);
Object value = PropertyUtils.getProperty(currentObj, key);
if (value instanceof Date) {
value = CommonUtil.date2String((Date) value,
CommonUtil.DATE_FORMAT);
}
value = Constant.transfer(key,value);
key = "__" + key + "__";
value = value == null ? "" : value;
tagString = tagString.replaceAll(key, value.toString());
}
}
System.out.println("doAfterBody = " + tagString);
JspWriter out = bodyContent.getEnclosingWriter();
bodyContent.clearBody();
out.println(tagString);
JspWriter out = bodyContent.getEnclosingWriter();
bodyContent.clearBody();
out.println(tagString);
index++;
if (iter.hasNext()){
this.currentObj = iter.next();
}else{
this.currentObj = null;
}
return EVAL_BODY_AGAIN;
} else {
return SKIP_BODY;
}
if (iter.hasNext()){
this.currentObj = iter.next();
}else{
this.currentObj = null;
}
return EVAL_BODY_AGAIN;
} else {
return SKIP_BODY;
}
} catch (Exception ex) {
ex.printStackTrace();
throw new JspException("IO problems during ListTag's doStartTag "
+ ex.getMessage());
}
ex.printStackTrace();
throw new JspException("IO problems during ListTag's doStartTag "
+ ex.getMessage());
}
}
public int doEndTag() throws JspException {
try {
try {
} catch (Exception ex) {
ex.printStackTrace();
throw new JspException("IO problems during ListTag's doStartTag "
+ ex.getMessage());
}
return EVAL_BODY_INCLUDE;
}
ex.printStackTrace();
throw new JspException("IO problems during ListTag's doStartTag "
+ ex.getMessage());
}
return EVAL_BODY_INCLUDE;
}
public void setBodyContent(BodyContent bodyContent) {
System.out.println("setBodyContent...");
this.bodyContent = bodyContent;
}
System.out.println("setBodyContent...");
this.bodyContent = bodyContent;
}
public void doInitBody() throws JspTagException {
System.out.println("doInitBody....");
}
System.out.println("doInitBody....");
}
public void setListName(String listName) {
this.listName = listName;
}
public String getListName() {
return listName;
}
return listName;
}
public void setCurrentObj(Object currentObj) {
this.currentObj = currentObj;
}
this.currentObj = currentObj;
}
public Object getCurrentObj() {
return currentObj;
}
return currentObj;
}
public void setScope(String scope) {
this.scope = scope;
}
this.scope = scope;
}
public String getScope() {
return scope;
}
}
return scope;
}
}