首先,要纠正下在《自定义-扩展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 "onclick=\"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函数就不写出来了 }