首先,要纠正下在《自定义-扩展struts2的标签》一文中笔者的分析。在该文中笔者说,
最近在做j2ee的项目,需要封装很多标签,发现直接从BodyTagSupport继承的话,无法获取valuestack,也无法借用struts的国际化解决方案。所以需要扩展struts的标签。
最近研究发同,其实即使从BodyTagSupport类继承来实现自定义的标签类,也可以取到valuestack.,如下所示:
ValueStack stack = TagUtils.getStack(pageContext);
最近实现的一个日期控件就是这样做的:
package com.jdgm.common.tag;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.views.jsp.TagUtils;
import com.jdgm.framework.model.UiItem;
import com.jdgm.platform.ConstantsPF;
import com.jdgm.platform.common.enums.QueryControlType;
import com.jdgm.platform.common.enums.QueryOperatorType;
import com.jdgm.platform.common.tag.CommonStrutsTag;
import com.jdgm.platform.components.log.LogUtil;
import com.opensymphony.xwork2.util.ValueStack;
/**
*
* @author zhangpf 20120801
* 因为之前使用的jscalendar的诸多问题,在当前项目中不得不扩展自己的控件,使用My97Datepicker
*/
public class Calendar extends BodyTagSupport{
private String id="";
private String name="";
private String value="";
/**
* 日期格式
* 年月日:yyyy-MM-dd
* 年月日 时分秒:yyyy-MM-dd HH:mm:ss
*/
private String format="yyyy-MM-dd";
/**
* 当只读为true是,不会显示输入框右侧的图片,也不能打开日期编辑窗口
*/
private String readonly="false";
private String width="150";
@Override
public int doEndTag() throws JspException {
try{
String content ="<input readonly type='text' id=\"%s\" name=\"%s\" value='%s' style='width:%s' %s > \n %s";
// 取得值栈,实现回显功能
ValueStack stack = TagUtils.getStack(pageContext);
String valueStr="";
if(stack!=null)
{
Object obj=stack.findValue(name);//取出的对象,可能是timestamp也可能是String
if(obj!=null)
{
//把取得值转换成用户设置的格式
SimpleDateFormat formatter = new SimpleDateFormat(this.getFormat());
Date date=null;
if(obj instanceof Timestamp)
date=formatter.parse(((Timestamp)obj).toString());
else if(obj instanceof Date)
date=(Date)obj;
else
date=formatter.parse(String.valueOf(obj));
if(date!=null)
valueStr=formatter.format(date);
}
if(StringUtils.isNotBlank(valueStr))
value=valueStr;
}
String out=String.format(content, this.getId(),this.getName(),value,this.getWidth(),this.getClickAction(),this.getImage());//
pageContext.getOut().println(out);
}
catch(Exception e)
{
LogUtil.error("生成日历控件失败", e);
}
return EVAL_PAGE;
}
/**
* 点击动作的实现js
* 用于输入框和日历图标的点击事件
* @return
*/
private String getClickAction()
{
if(readonly.toUpperCase().equals("TRUE"))
return "";
return "οnclick=\"WdatePicker({el:'"+this.getId()+"',dateFmt:'"+this.getFormat()+"'})\" ";
}
/**
* 输出右侧的日历图标
* @return
*/
private String getImage()
{
if(readonly.toUpperCase().equals("TRUE"))
return "";
return " <img src=\""+ConstantsPF.URL_WEBSITE+"/img/calendar.png\" width=\"16\" height=\"16\" \n"
+this.getClickAction()
+" style=\"cursor:hand\"> ";
}
....................//各变量的get/set函数就不写出来了
}