自定义—扩展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的实例,也可以通过类属性
 *       来做与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 propertys = new ArrayList();
	{
		propertys.add("ctx");
		propertys.add("id");
		propertys.add("showdiv");

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

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

 

你可能感兴趣的:(struts2,struts,扩展,string,exception,regex,action)