struts-自定义标签

struts2 自定义标签说明:

    A、继承ComponentTagSupport,获取jsp页面中的属性值

    B、承Component类是为了从Struts2中的ValueStack中获得相对应的值
    C、创建标签库的描述文件
    D、web.xml中添加标签库说明
    E、JSP页面中添加标签库说明,及使用标签

1、继承ComponentTagSupport类是为了获得JSP页面中用户自定义的标签中设置的属性值,并包装成Component对象

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.opensymphony.xwork2.util.ValueStack;

/**
 * 自定义超链接标签
 * 作用:检测用户是否有操作该标签的权限,如果该用户有操作该标签的权限,在页面显示超链接
 * 如果用户没有操作该标签的权限,页面上不输出该标签
 * */
public class ATag extends ComponentTagSupport {
	
	private String params;	
	private String opcode;
	
	private String style;
	private String id;
	private String clasz;
	private String title; //标签属性title
	private String onclick ;
	
	private HttpServletRequest req;
	private HttpServletResponse res;

	@Override
	public Component getBean(ValueStack stack, HttpServletRequest req,
			HttpServletResponse res) {
		this.req = req;
		this.res = res;		
		return new A(stack,req);
	}

	public void setParams(String params) {
		this.params = params;
	}

	public void setOpcode(String opcode) {
		this.opcode = opcode;
	}

	public void setCalcpid(String calcpid) {
		this.calcpid = calcpid;
	}

	public void setReq(HttpServletRequest req) {
		this.req = req;
	}

	public void setRes(HttpServletResponse res) {
		this.res = res;
	}

	public void setStyle(String style) {
		this.style = style;
	}

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

	public void setClasz(String clasz) {
		this.clasz = clasz;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public void setOnclick(String onclick) {
		this.onclick = onclick;
	}

	@Override
	protected void populateParams() {  
        super.populateParams();       
        A a = (A)component;
        a.setClasz(clasz);
        a.setId(id);
        a.setOpcode(opcode);
        a.setParams(params);
        a.setStyle(style);
        a.setTitle(title);
        a.setOnclick(onclick);
        HttpSession session = req.getSession();
		AuthBean authBean = (AuthBean)session.getAttribute(Constants.ATTR_AUTHBEAN);
		a.setAuthBean(authBean);
	}
	

}

注释:ATag重写的两个方法是:
(1).public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res);
此方法就是获得一个基本类的对象。在基本类里面需要有传入ValueStack的构造函数,如果基本类逻辑里面需要request或者response,那么需要有传入ValueStack stack, HttpServletRequest req, HttpServletResponse res的构造函数;
(2).protected void populateParams()此方法是用来将JSP页面传来的属性值赋给基本类。这里是继承来的,所以首先调用super的相应方法。第一个方法返回的对象就是全局的一个Component对象,populateParams方法里面使用的对象。请看ComponentTagSupport源码:


public abstract class ComponentTagSupport extends StrutsBodyTagSupport {
    protected Component component;

    public abstract Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res);

    public int doEndTag() throws JspException {
        component.end(pageContext.getOut(), getBody());
        component = null;
        return EVAL_PAGE;
    }

    public int doStartTag() throws JspException {
        component = getBean(getStack(), (HttpServletRequest) pageContext.getRequest(), (HttpServletResponse) pageContext.getResponse());
        Container container = Dispatcher.getInstance().getContainer();
        container.inject(component);
        
        populateParams();
        boolean evalBody = component.start(pageContext.getOut());

        if (evalBody) {
            return component.usesBody() ? EVAL_BODY_BUFFERED : EVAL_BODY_INCLUDE;
        } else {
            return SKIP_BODY;
        }
    }

    protected void populateParams() {
    }

    public Component getComponent() {
        return component;
    }
}

ComponentTagSupport类中声明了全局变量component,doStartTag()方法调用抽象方法getBean()生成component对象,这就是为什么我们要覆写getBean()方法。然后调用了  populateParams()方法,最后调用了component.start。

EVAL_BODY_INCLUDE:把Body读入存在的输出流中,

doStartTag()函数可用 EVAL_PAGE:继续处理页面,

doEndTag()函数可用 SKIP_BODY:忽略对Body的处理,

doStartTag()和doAfterBody()函数可用

SKIP_PAGE:忽略对余下页面的处理,

doEndTag()函数可用

EVAL_BODY_TAG:已经废止,由EVAL_BODY_BUFFERED取代 EVAL_BODY_TAG:申请缓冲区,由setBodyContent()函数得到的BodyContent对象来处理tag的body,如果类实现了BodyTag,那么doStartTag()可用,否则非法。

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

import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.components.Component;


import com.opensymphony.xwork2.util.ValueStack;

public class A extends Component {
	
	private String params;	//参数
	private String opcode; 
	
	private String style; //标签属性风格
	private String id; //标签属性id
	private String clasz; //标签属性calss
	private String title; //标签属性title
	private String onclick ; //标签属性onclick
	
	private AuthBean authBean;
	HttpServletRequest req ;
	
	public A(ValueStack stack,HttpServletRequest req) {		
		super(stack);
		this.req = req;
	}

	public String getStyle() {
		return style;
	}

	public void setStyle(String style) {
		this.style = style;
	}

	public String getId() {
		return id;
	}

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

	public String getParams() {
		return params;
	}
	
	public void setParams(String params) {
		this.params = params;
	}
	
	public String getOpcode() {
		return opcode;
	}

	public void setOpcode(String opcode) {
		this.opcode = opcode;
	}

	public String getClasz() {
		return clasz;
	}

	public void setClasz(String clasz) {
		this.clasz = clasz;
	}


	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getOnclick() {
		return onclick;
	}

	public void setOnclick(String onclick) {
		this.onclick = onclick;
	}

	public void setAuthBean(AuthBean authBean) {
		this.authBean = authBean;
	}

	@Override
	public boolean start(Writer writer) {
		boolean flag = false;//是否能访问本连接
		UserRoleOperate operate = null;
		if(authBean != null){
			authBean.getOperate();
			//省略了业务逻辑
			flag= true;
		}
		
		if(flag){
			//如果有访问权限
			StringBuffer href = new StringBuffer();
			String contextpath = req.getContextPath();
			String url = operate.getUrl();
			
			href.append(contextpath+url);			
			
			StringBuffer link = new StringBuffer();
			link.append("<A ");
			
			//首先添加action
			//判断是否为空,如果为空的话,不写href属性
			if(!StringUtils.isBlank(url)){
				link.append(" href=\"").append(href);
				//添加参数
				if(!StringUtils.isBlank(params)){
					link.append("?"+params);
				}
				link.append("\"");
			}
			
			//添加标签id属性
			if(!StringUtils.isBlank(id)){
				link.append(" id=\""+id+"\"");
			}
			
			//添加标签style属性
			if(!StringUtils.isBlank(style)){
				link.append(" style=\""+style+"\"");
			}
			
			//添加标签calss属性
			if(!StringUtils.isBlank(clasz)){
				link.append(" class=\""+clasz+"\"");
			}
			
			if(!StringUtils.isBlank(title)){
				link.append(" title=\""+title+"\"");
			}
			
			if(!StringUtils.isBlank(onclick)){
				link.append(" onclick=\""+onclick+"\"");
			}
			link.append(">");
			System.err.println("----------------->"+link);
			
			try {
				writer.write(link.toString());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return super.start(writer);
	}

	@Override
	public boolean end(Writer writer, String body) {
		boolean flag = false;//是否能访问本连接
		UserRoleOperate operate = null;
		if(authBean != null){
			if(authBean != null){
				authBean.getOperate();
				//省略了业务逻辑
				flag= true;
			}
		}
		
		if(flag){
			try {
				writer.write("</A>");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return super.end(writer, body);
	}
	
	

}
自己需要输出的逻辑通过writer输出字符串

这里请注意形式参数body中数据为空,为什么呢?为什么标签体的内容没有获得呢?,如果我们想自己控制body的显示呢?

获取body的方法时,重写Component类中的方法:

/**
     * Overwrite to set if body shold be used.
     * @return always false for this component.
     */
    public boolean usesBody() {
        return true;
    }
设置返回值true,这时候你就可以获得body的值了,自己控制显示的情况。

3、创建标签库的描述文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
  <tlib-version>2.2.3</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>layout</short-name>
  <uri>/struts-layout-tags</uri>
  <display-name>"Struts Tags"</display-name>
  <description><![CDATA["To make it easier to access dynamic data;
                    the Apache Struts framework includes a library of custom tags.
                    The tags interact with the framework's validation and internationalization features;
                    to ensure that input is correct and output is localized.
                    The Struts Tags can be used with JSP FreeMarker or Velocity."]]></description>

  <tag>
  <name>a</name>
    <tag-class>com.fangdo.core.view.ATag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
      <name>opcode</name>
      <required>true</required>
      <rtexprvalue>false</rtexprvalue>
      <description><![CDATA[opcode for this link]]></description>
    </attribute>
    <attribute>
      <name>calcpid</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[calc product for this link]]></description>
    </attribute>
    <attribute>
      <name>params</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[params  for this link]]></description>
    </attribute>
    <attribute>
      <name>style</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[style for this link]]></description>
    </attribute>
    <attribute>
      <name>id</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[id for this link]]></description>
    </attribute>
    <attribute>
      <name>clasz</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[clasz for this link]]></description>
    </attribute>
     <attribute>
      <name>title</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[title for this link]]></description>
    </attribute>
    <attribute>
      <name>onclick</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[onclick for this link]]></description>
    </attribute>
  </tag>
</taglib>
4、 web.xml中添加标签库说明
<jsp-config>
		<taglib>
			<taglib-uri>/struts-layout-tags.tld</taglib-uri>
			<taglib-location>/WEB-INF/struts-layout-tags.tld</taglib-location>
		</taglib>
</jsp-config>
5、 JSP页面中添加标签库说明,及使用标签
<%String jxc4_param = "id="+ cc.getId()+"&height=450&width=750"; %>
					<layout:a  opcode="JXC_4" params="<%=jxc4_param %>" clasz="thickbox" title="商户详情">
						详情
					</layout:a>




转载于:https://my.oschina.net/winHerson/blog/117313

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值