码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-03-31 16:08:58      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:struts2   标签   源码   

最近在做学习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标签去判断是否存在权限,那么感觉代码不会像这样简洁了吧。。


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

标签:struts2   标签   源码   

原文地址:http://blog.csdn.net/u013762572/article/details/44779745

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!