自定义—扩展struts2的标签

     最近在做j2ee的项目,需要封装很多标签,发现直接从BodyTagSupport继承的话,无法获取valuestack,也无法借用struts的国际化解决方案。所以需要扩展struts的标签。

     看了网上很多的扩展方法,觉得只能做为参考或示例,但却一点也不实用。索性自已用ComponentTagSupport来做个封装。

     下面是关于ComponentTagSupport的一些介绍:

 

          在struts2.x中实现自定义标签时,继承的2个类分别是org.apache.struts2.views.jsp.ComponentTagSupport   和

org.apache.struts2.components.Component.

 

ComponentTagSupport:

         实际上是对BodyTagSupport的一次封装,继承ComponentTagSupport类是为了获得JSP页面中用户自定义的标签中设置的属性值,并包装成Component对象。

Component:
         继承Component类是为了从Struts2中的ValueStack中获得相对应的值。

 

    下面给出我的源码,代码结构我就不讲了。需要它的朋友自然看得懂。

 

package com.jdgm.platform.common.tag;

import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.jdgm.framework.utils.BeanUtils;
import com.jdgm.framework.utils.ResourceUtil;
import com.jdgm.framework.utils.Utils;
import com.jdgm.platform.ConstantsPF;
import com.jdgm.platform.components.log.LogUtil;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.ValueStack;

/**
 *
 * struts的标签扩展从这里继承
 * 相比于从BodyTagSupport扩展,具有以下优势:
 * 1)国际化的解决:CommonStrutsTag的子类可以享有和struts自带标签一样的国际化解决方案
 * 2)值栈:CommonStrutsTag的子类,可以获取valuestack的实例,也可以通过类属性<valueproperty>
 *       来做与action对应属性的双向绑定,即值提交与值填充<具体参见属性valueproperty的说明>
 *
 * @author zhangpf
 *
 */
public abstract class CommonStrutsTag extends ComponentTagSupport {

	/**
	 * 网站的URL地址,系统赋值。
	 */
	protected  String ctx;

	protected String id;

	protected String templateFile;

	protected String showdiv;

	public String getShowdiv() {
		return showdiv;
	}

	public void setShowdiv(String showdiv) {
		this.showdiv = showdiv;
	}

	/**
	 * 所有属性列表
	 */
	protected List<String> propertys = new ArrayList<String>();
	{
		propertys.add("ctx");
		propertys.add("id");
		propertys.add("showdiv");

	}
	/**
	 * 需要在字类中特殊处理的属性集合
	 */
	protected List<String> specproperty = new ArrayList<String>();

	/**
	 * URL相关的属性
	 */
	protected List<String> urlproperty = new ArrayList<String>();

	/**
	 * 需要从valuestack中取值的相关的属性  <br/>
	 * 比如:控件具有一属性:titlefield,值为"model.title" <br/>
	 * 对应的控件源码为:< input  name="%{titlefield}" /> <br/>
	 * 这样的话,就完成了与action中属性model.title的单向绑定,即提交表单时<br/>
	 * input的值会自动填充到action中的对应属性。但是却无法做到把action中属性的值<br/>
	 * 反向填充到input控件。若想做到这一点,可修改控件源码为:<br/>
	 * < input  name="%{titlefield}"  value="%{title}"/><br/>
	 * 同时,在tag子类中,再定义一属性title,并把添加到valueproperty中,<br/>
	 * 然后在init()中,为title赋值为:"model.title",这样就完成了action属性值与input控件的反向绑定<br/>
	 * 即通过action地址打开jsp页面时,若action中model.title不为空,则会把该属性的值自动赋给控件 <br/>
	 */
	protected List<String> valueproperty = new ArrayList<String>();

	@Override
	public Component getBean(ValueStack arg0, HttpServletRequest arg1,
			HttpServletResponse arg2) {
		init();
		CommonStrutsComponent cmp=new CommonStrutsComponent(arg0);

		return cmp;
	}
	@Override
	 protected void populateParams() {
		  super.populateParams();

		  CommonStrutsComponent cmp=(CommonStrutsComponent)component;
		  cmp.setHtmlContent(toHTML());
	}
	/**
	 * 该方法用于在构建标签前,对标签内的各属性做预处理用的
	 * 主要方便子类扩展
	 */
    protected  void init(){

    }
    final protected String toHTML() {
		ctx=ConstantsPF.URL_WEBSITE;
		try {
			StringBuilder string = new StringBuilder(IOUtils.toString(
					CommonTag.class.getResourceAsStream(templateFile), "UTF-8"));

			for (String pro : propertys) {
				if(specproperty.contains(pro)
					||valueproperty.contains(pro)
					||urlproperty.contains(pro))
					continue;

				String regex = "%{" + pro + "}";
				while (string.indexOf(regex) != -1) {
					int index = string.indexOf(regex);
					String provalue = String.valueOf( PropertyUtils.getProperty(this,pro));
					if (StringUtils.isNotBlank(provalue)) {

						string.replace(index, index + regex.length(),provalue);

					} else {
						provalue = "";
						string.replace(index, index + regex.length(), provalue);
					}
				}
			}
			dealUrlProperty(string);
			dealValueProperty(string);
			dealSpecProperty(string);
			return string.toString();	

		} catch (Exception e) {
			LogUtil.error("生成控件失败", e);
		}
		 return "";
	 }
    /**
     * url 相关的处理
     * @param string
     * @throws Exception
     */
     protected void dealUrlProperty(StringBuilder string)throws Exception
     {
    	 for (String pro : urlproperty) {

 			String regex = "%{" + pro + "}";

			while (string.indexOf(regex) != -1) {
				int index = string.indexOf(regex);
				String provalue = String.valueOf( PropertyUtils.getProperty(this,pro));
				if (StringUtils.isNotBlank(provalue)) {

					provalue = ctx + provalue;
					string.replace(index, index + regex.length(),provalue);

				} else {
					provalue = "";
					string.replace(index, index + regex.length(), provalue);
				}
			}
 		}
     }
 	/**
 	 * 需要从valuestack中取值的相关的属性
 	 */
	 protected void dealValueProperty(StringBuilder string) throws Exception
	 {

		for (String pro : valueproperty) {

			String regex = "%{" + pro + "}";
			while (string.indexOf(regex) != -1) {
				int index = string.indexOf(regex);
				String field = String.valueOf(PropertyUtils.getProperty(this,pro));

				if (StringUtils.isNotBlank(field)) {
					String fieldValue=this.getStack().findString(field);
					if(fieldValue==null)
						fieldValue="";
						string.replace(index, index + regex.length(),fieldValue);
				}
				else {

					string.replace(index, index + regex.length(), "");
				}
			}
		}
	 }

	 /**
	 * 处理特殊属性,主要用于子类扩展
	 */
	protected  void dealSpecProperty(StringBuilder string) throws Exception{

	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public  String getCtx() {
		return ctx;
	}

	public  void setCtx(String ctx1) {
		ctx = ctx1;
	}

}
class CommonStrutsComponent extends Component {
	private String htmlContent;

	public String getHtmlContent() {
		return htmlContent;
	}

	public void setHtmlContent(String htmlContent) {
		this.htmlContent = htmlContent;
	}

	public CommonStrutsComponent(ValueStack stack) {
		super(stack);

	}
	public boolean start(Writer writer) {

		 boolean result = super.start(writer);
		 try
		 {

			 writer.write(htmlContent);
		 }
	    catch (Exception ex) {
	    	ex.printStackTrace();
	    }
		 return result;
	}
}

 

 对于上面的CommonStrutsTag的类使用,下面给了一个简单例子,看了后,你会觉得因为CommonStrutsTag,再写自定义标签的时候,非常简单,秒秒中的事。哈哈

DemoTag.java

package com.jdgm.platform.common.tag;

import java.util.Locale;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.jdgm.framework.utils.BeanUtils;
import com.jdgm.framework.utils.ResourceUtil;
import com.jdgm.framework.utils.Utils;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.ValueStack;

/**
 *
 * tab页控件

 * @author zhangpf
 *
 */
public class DemoTag extends CommonStrutsTag {

	{
		templateFile="demotag.txt";
	}

	{
		propertys.add("field");
		valueproperty.add("value");

	}

	private String field;
	private String value;
	public String getField() {
		return field;
	}
	public void setField(String field) {
		this.field = field;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}

}

 

demotag.txt:

<input type="text" name="%{field}" value="%{value}"  />

 

时间: 2024-11-03 19:21:19

自定义—扩展struts2的标签的相关文章

Silverlight 5 beta新特性探索系列:8.Silverlight 5中自定义扩展标记

在Silverlight 5中新增了自定义扩展标记,它通过继承于 MarkupExtension 类,重载该类中的ProvideValue方法以判断得到相应的返回值,以设置被绑定控件的属性. 下面我们通过一个最为简单的实例来理解自定义扩展标记是如何工作的. 第一步:新建一个UserMarkExtension.cs类,注意UserMark(扩展标记名)+Extension.cs(固定的后缀)=UserMarkExtension.cs 第二步:设置3个可被访问的属性标签LBText,LBWidth,

struts2 cssclass:Struts2 checkboxlist标签 设置cssClass属性生成的html代码中check没有class属性问题

使用struts2 checkboxlist标签设置cssClass属性后,发现生成的html代码中 input 标签并没有class属性.打开checkboxlist.ftl看,内容如下:<input type="checkbox" name="${parameters.name?html}" value="${itemKeyStr?html}" id="${parameters.name?html}-${itemCount}&

SharePoint 2013自定义扩展菜单的例子

接上文:http://www.bianceng.cnhttp://www.bianceng.cn/web/sharepoint/201406/41934.htm 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomAction Id="CustomAction1" Description="博客园-霖雨" Title="博客园-霖雨" GroupId="GeneralSettings"

java集合问题-关于Struts2迭代标签的问题

问题描述 关于Struts2迭代标签的问题 想请教下各位大神,我在action里面有2个集合,想在JSP页中遍历出来,我想要的功能是第一个集合内容全部显示,第二个集合内容只显示与第一个集合匹配的元素.提供下思路

NHibernate3.0剖析:Query篇之NHibernate.Linq自定义扩展

系列引入 NHibernate3.0剖析系列分别从Configuration篇.Mapping篇.Query篇.Session策略篇.应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本.如果你还不熟悉NHibernate,可以快速阅读NHibernate之旅系列文章导航系列入门,如果你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧. NHibernate专题:http://kb.cnblogs.com

自定义实现struts2中的国际化机制

最近一段时间,一直在研究struts2中的国际化实现方案. 对于struts2中标签的国际化中,key值的搜索顺序如下: 假设我们在某个ChildAction中调用了getText("user.title"),Struts 2.0的将会执行以下的操作: (1)优先加载系统中保存在ChildAction的类文件相同位置,且baseName为ChildAction的系列资源文件. (2)如果在(1)中找不到指定key对应的消息,且ChildAction有父类ParentAction,则加载

Heritrix3.x自定义扩展Extractor

一.引言: Heritrix3.x与Heritrix1.x版本差异比较大,全新配置模式的引入+扩展接口的变化,同时由于说明文档的匮乏,给Heritrix的开发者带来困惑,前面的文章已经就Heritrix的配置部署和运行做了说明,本文就Heritrix3.x版本就Extractor扩展做出实例说明. 二.配置说明 Heritrix3.x的WebUI发生了变化,不在是原来那种WebUI选择模式,而是变成了在线配置文件直接编辑模式.在这里自定义的Extractor要想加入Heritrix运行,首先需要

如何使用struts2的标签迭代出HashMap中的List的记录?

问题描述 我Action中有一个HashMap,里面存放的是以ID为key,List为value的数据,请问怎样才能使用struts2的标签迭代出里面的数据?我目前是这样写的:<s:iterator value="answerHashMap"> <s:iterator value="<s:property value="subjectId"/>"> <s:property value="answ

php自定义扩展名获取函数示例_php技巧

本文实例讲述了php自定义扩展名获取函数.分享给大家供大家参考,具体如下: <?php $url = "http://www.abc.com/abc/de/fg.php?id=1"; //这个是自己写的 function getUrl($url) { $date = explode('?', $url); $date = basename($date[0]); $date = explode('.', $date); return $date[1]; } var_dump(get