Struts2自定义标签——通过自定义标签实现权限控制

  • 近期在开发中遇到一种需求:根据用户的权限决定是否显示某操作按钮。

例如:若用户拥有删除数据的权限,则在界面中显示“删除”按钮;若用户无该权限,则界面中不显示相应按钮。

这样,就需要用到自定义标签了。


要定义Struts2的自定义标签,只需三步:

  1. 定义一个Component类,并继承自org.apache.struts2.components.Component;
  2. 定义一个Tag类,并继承自import org.apache.struts2.views.jsp.ComponentTagSupport;
  3. 在WEB-INF目录下创建相应的LTD文件

下面就来逐一实现:

step1:定义Component类

Component,顾名思义是“组件”。这其中封装了标签需要的处理逻辑。

我们定义的Component类需要继承org.apache.struts2.components.Component;。在父类中,有两个方法比较重要,分别是:start()方法和end()方法,这两个方法分别对应了开始标签结束标签,我们可以通过这两个方法来对标签进行操作。
此外,若标签需要属性,则应该在本类中定义相应属性,并提供相应的get()set()方法,用于封装这些属性。
然后,我们就可以对标签及属性进行处理了。

这里给出我的代码,实现的功能是:将当前每一个要显示的按钮的URL地址用户所拥有的权限对应的URL比较,若用户有权限访问该URL,则显示按钮,否则将不显示任何内容。

package qdgxy.tag;

import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.components.Component;
import qdgxy.domain.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.Writer;

public class AComponent extends Component {

    private String actionURL;
    private String value;
    private String onclick = "";
    private HttpServletRequest request;

    @Override
    public boolean start(Writer writer) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user.hasPrivilegeByURL(actionURL)) {
            try {
                writer.write("<a href='" + formatURL(actionURL) + "' onClick='" + onclick + "'>" + value + "</a>");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;
        } else {
            return super.start(writer);
        }
    }

    private String formatURL(String url) {
        int index = url.indexOf('?');
        if (index != -1) {
            String params = url.substring(index);
            url = url.substring(0, index) + ".action" + params;
        } else {
            url = url + ".action";
        }
        return url;
    }

    public AComponent(ValueStack stack, HttpServletRequest request) {
        super(stack);
        this.request = request;
    }

    public String getActionURL() {
        return actionURL;
    }

    public void setActionURL(String actionURL) {
        this.actionURL = actionURL;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getOnclick() {
        return onclick;
    }

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

step2:定义Tag类

Tag类,说白了就是我们所使用的标签。

创建Tag类,首先需要继承org.apache.struts2.views.jsp.ComponentTagSupport类。

然后,重写getBean()方法和populateParams()方法。

  • getBean()方法用于返回标签组件的实例,即我们step1中创建的组件。
  • populateParams()方法用于填充属性,即:将我们标签中的属性封装到标签类中。因此,我们在Tag类中也需要定义相应属性并提供get()set()方法。

这样,我们就可以指定组件对标签进行处理。

可能有人会有疑问:为什么我们不将标签处理逻辑直接写在Tag类中,而是要单独定义一个Component类呢?
这是因为:Struts2支持多种表现层技术,使用Component可以对不同的表现层技术使用不同的处理方式,提高程序的可扩展性。

给出我的代码:
这段代码实现的功能是:使用step1中定义的组件对标签进行处理。

package qdgxy.tag;

import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

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

public class ATag extends ComponentTagSupport {

    private String actionURL;
    private String value;
    private String onclick = "";

    @Override
    public Component getBean(ValueStack valueStack, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        return new AComponent(valueStack, httpServletRequest);
    }

    @Override
    protected void populateParams() {
        AComponent component = (AComponent) getComponent();
        component.setActionURL(actionURL);
        component.setValue(value);
        component.setOnclick(onclick);
    }

    public String getOnclick() {
        return onclick;
    }

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

    public String getActionURL() {
        return actionURL;
    }

    public void setActionURL(String actionURL) {
        this.actionURL = actionURL;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

step3:在WEB-INF目录下创建TLD文件

TLD文件描述了标签的语法,如:标签有哪些属性,标签的属性是否支持表达式等内容。

我们在JSP中使用标签前,都需要引入相应的标签库,所以我们需要定义TLD文件,使JSP中能使用我们的自定义标签。

给出我定义的TLD文件,其中有几个简单的属性。

<?xml version="1.0" encoding="UTF-8"?>
<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>2.0</jsp-version>
    <short-name>oa</short-name>
    <uri>/WEB-INF/OATag.tld</uri>
    <tag>
        <name>a</name>
        <tag-class>qdgxy.tag.ATag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>actionURL</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>value</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>onclick</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

其中:

  • short-name:相当于前缀
  • uri:就是<%@taglib>中的uri
  • tag:一个标签
  • tag-class:标签类,就是我们的Tag类
  • body-content:标签体中能写的内容
  • attribute:属性
  • name:属性名
  • required:是否必须
  • rtexprvalue:是否支持表达式

TLD文件中的内容还有很多,更多内容可以Google一下就能获得,在此就不再赘述。


至此,我们就可以在JSP中使用自定义标签了。

使用的方式:
1. 引入标签库:<%@ taglib prefix="oa" uri="/WEB-INF/OATag.tld" %>
2. 使用标签:<oa:a actionURL="user_editUI?id=${id}" value="修改"/>

这样,在用户查看当前页面时,就能够根据用户的权限来选择是否显示操作按钮。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值