最近在做学习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标签去判断是否存在权限,那么感觉代码不会像这样简洁了吧。。
原文地址:http://blog.csdn.net/u013762572/article/details/44779745