修改struts2中UI标签的<s:a>进行权限控制

最近在做学习S2SH时,有一个模块式权限控制,就是对用户的操作存在权限分级操作,即不是所有的用户都可以访问全部数据。下面说一下这次我们的做法。

1.所谓权限控制,就是对URL地址的控制,用户角色中不存在该权限,那么该url地址对用户是不起反应的(用户点击无反应),最好是不可见的。整体的思路就是这样,通过对UI标签的控制而达到对权限的控制。

2.我们使用的是struts2中的a标签,而非使用简单的html中a标签。原因是在<s:a>标签的源码中存在doStartTag()和doEndTag()方法.假设存在以下标签:

<s:a action="user_delete.action?id=%{id}"  onClick="return delConfirm()">删除</s:a>

那么在执行doStartTag()方法之后,标签会读到<s:a action="user_delete.action?id=%{id}"  onClick="return delConfirm()">,并没有将标签信息读完! 在执行完doEndTag()方法之后,标签会将剩下的配置读完。所以要检查是否存在权限,需要在doEndTag()方法中增加自己的逻辑。

3.下面来简单介绍一下如下修改UI之<s:a>源码。在struts2-core源码包下找到META-INF文件夹(不出意外的话应该是最下面位置),打开里面的struts-tags.tld.通过搜索<name>a</name>找到标签中的对应的原始类org.apache.struts2.views.jsp.ui.AnchorTag,然后打开该源码(打不开也没关系,等会你拷我的源码就可以了。因为我装了GD-GUI插件,建议打不开jar文件的你也装一下).在你的项目src下新建一个org.apache.struts2.views.jsp.ui的包,在包内新建一个AnchorTag类(是的,与上面的类一模一样,原因很简单,jvm会优先加载src下的class文件,src下的class文件找不到就去外部jar包中查找),代码如下:

package org.apache.struts2.views.jsp.ui;

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

import org.apache.struts2.components.Anchor;
import org.apache.struts2.components.Component;

import com.it.entity.User;
import com.opensymphony.xwork2.util.ValueStack;

public class AnchorTag extends AbstractClosingTag {
	private static final long serialVersionUID = -1034616578492431113L;
	protected String href;
	protected String includeParams;
	protected String scheme;
	protected String action;
	protected String namespace;
	protected String method;
	protected String encode;
	protected String includeContext;
	protected String escapeAmp;
	protected String portletMode;
	protected String windowState;
	protected String portletUrlType;
	protected String anchor;
	protected String forceAddSchemeHostAndPort;

	public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
		return new Anchor(stack, req, res);
	}

	/**
	 * 自定义的代码
	 */
	@Override
	public int doEndTag() throws JspException {
		User user = (User) pageContext.getSession().getAttribute("user");
<span style="white-space:pre">		</span>//user.hasThisURLPrivilege(String url)是配对自己是否用于权限
		if(user != null && user.hasThisURLPrivilege(action)){
			return super.doEndTag();
		}else{
			return EVAL_PAGE ;
		}
	}

	protected void populateParams() {
		super.populateParams();

		Anchor tag = (Anchor) this.component;
		tag.setHref(this.href);
		tag.setIncludeParams(this.includeParams);
		tag.setScheme(this.scheme);
		tag.setValue(this.value);
		tag.setMethod(this.method);
		tag.setNamespace(this.namespace);
		tag.setAction(this.action);
		tag.setPortletMode(this.portletMode);
		tag.setPortletUrlType(this.portletUrlType);
		tag.setWindowState(this.windowState);
		tag.setAnchor(this.anchor);

		if (this.encode != null) {
			tag.setEncode(Boolean.valueOf(this.encode).booleanValue());
		}
		if (this.includeContext != null) {
			tag.setIncludeContext(Boolean.valueOf(this.includeContext)
					.booleanValue());
		}
		if (this.escapeAmp != null) {
			tag.setEscapeAmp(Boolean.valueOf(this.escapeAmp).booleanValue());
		}
		if (this.forceAddSchemeHostAndPort != null)
			tag.setForceAddSchemeHostAndPort(Boolean.valueOf(
					this.forceAddSchemeHostAndPort).booleanValue());
	}

	public void setHref(String href) {
		this.href = href;
	}

	public void setEncode(String encode) {
		this.encode = encode;
	}

	public void setIncludeContext(String includeContext) {
		this.includeContext = includeContext;
	}

	public void setEscapeAmp(String escapeAmp) {
		this.escapeAmp = escapeAmp;
	}

	public void setIncludeParams(String name) {
		this.includeParams = name;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public void setScheme(String scheme) {
		this.scheme = scheme;
	}

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

	public void setPortletMode(String portletMode) {
		this.portletMode = portletMode;
	}

	public void setPortletUrlType(String portletUrlType) {
		this.portletUrlType = portletUrlType;
	}

	public void setWindowState(String windowState) {
		this.windowState = windowState;
	}

	public void setAnchor(String anchor) {
		this.anchor = anchor;
	}

	public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) {
		this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
	}
}

需要修改的方法就是在doTagEnd()中,存在于父类中。首先我们会获取该用户的信息,在User存在的情况下,我们进行判断,在用户拥有该权限时,执行

return super.doEndTag();

该方法的意思是:显示该超链接的信息,然后继续执行后面的代码。当用户不存在该权限时,执行

return EVAL_PAGE ;

该方法的意思是:不显示该超链接的信息(就是意味着该标签将不显示于JSP文件中了),然后继续执行后面的代码。

好了,我感觉我说清楚了,虽然这只是一个小知识,但是如果不使用的UI标签去判断是否存在权限,那么感觉代码不会像这样简洁了吧。。

时间: 2024-10-07 01:57:42

修改struts2中UI标签的<s:a>进行权限控制的相关文章

Struts2中UI标签之表单标签的一个例子

1.最近写了一篇文章,介绍了一下Struts2中UI标签的表单标签,文章地址为:http://blog.csdn.net/u012561176/article/details/44986183  因为缺少了个例子,大家看文字和表格也看不出什么效果来,所以今天来介绍一个例子,用Struts2中UI标签的表单标签实现一个个人信息的表单,但是有些表单标签没有演示出来,大家可以根据我介绍UI标签的表单标签来进行学习,这里只是给个例子. 2.首先新建一个Struts2项目,项目名为PersonMess

Struts2中UI标签之表单标签介绍

1.在Struts2中UI标签的表单标签分为两种:form标签本身和单个表单标签. 2.Struts2表单标签包括:form.textfield.password.radio.checkbox.checkboxlist.select.doubleselect.combobox.optiontransferselect.optgroup.updownselect.textarea.hidden.file.label.submit.token.head.datepicker.reset.richte

Struts2中UI标签之非表单标签

1.非表单标签主要用于在页面生成一些非表单的可视化元素,例如Tab页面,输出HTML页面的树形结构等.当然,非表单标签也包含在页面显示Action里封装的信息,非表单标签主要有如下几个: a:生成一个超级连接(link). actionerror:如果Action实例的getActionError()方法返回不为null,则该标签负责输出该方法返回的系列错误. actionmessage:如果Action实例的getActionMessage()方法返回不为null,则该标签负责输出该方法返回的

Struts2中datetimepicker标签

在以前的struts2版本中s:datetimepicker只需要在head标签处设置<s:head theme="ajax"/>,就可以直接使用s:datetimepicker的标签了.而在2.1.6版本中不能直接这样使用了,将datetimepicker移除了.原因是此标签调用了dojo的datetimepicker的库.所以现在使用的时候首先要导入一个库:struts2-dojo-plugin-2.1.6.jar.然后还要设置dojo的taglib<%@ tag

struts2中ognl标签详解

<body> <s:set name="age" value="61" /> <!-- if elseif else 参数test:决定标志里的内容是否显示的表达式,类型boolean 注:else标志没有这个参数 --> <h3>if语句</h3> <s:if test="{age>60}"> 老年人 </s:if> <s:elseif test=&

深入分析JavaWeb Item49 -- Struts2中常用标签与主题

一.非UI标签 1.property标签 property标签用于输出指定值: * default:可选属性, 如果需要输出的属性值为null,则显示该属性指定的值 * escape:可选属性,指定是否格式化HTML代码. * value: 可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值. 2.set标签 set标签用于将某个值放入指定范围. var:变量的名字,name,id和var表达的含义是一样的,name,id被var替代 scope:指定变量

深入分析JavaWeb 49 -- Struts2中常用标签与主题

一.非UI标签 1.property标签 property标签用于输出指定值: * default:可选属性, 如果需要输出的属性值为null,则显示该属性指定的值 * escape:可选属性,指定是否格式化HTML代码. * value: 可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值. 2.set标签 set标签用于将某个值放入指定范围. var:变量的名字,name,id和var表达的含义是一样的,name,id被var替代 scope:指定变量

struts2中的标签“# ”,“%{ }”,“%{# }”

理解值栈(ValueStack)与上下文(StackContext):            Struts2中有值堆栈和堆栈上下文的概念,你用 <s:debug />可以看出. 值栈中的对象的不使用#,非值栈中的对象使用#         当前action,或者处于action链中的action所拥有的属性,并且为该属性提供了getter和setter方法,那么在jsp中就不需要使用#,除此之外需要使用#,那么从这里你就可以知道action的属性如果提供了getter和setter方法,那么这

Struts2中 radio标签的详细使用方法

首先在页面中引入struts标签库: <%@ taglib prefix="s" uri="/struts-tags"%> 在JSP页面中创建单选按钮radio的方法: <s:radio list="#{'1':'先生','0':'女士'}" name="gender" value="1"/> 其中list中的键值对表示所有的选项,value表示设置的默认值,如果这个默认值是从后台传