权限模块__使用权限__显示有权限的链接1__思路分析
实现功能
导入源文件,找到AnchorTag.java类复制到工程中
AnchorTag.java
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 cn.itcast.oa.domain.User; import com.opensymphony.xwork2.util.ValueStack; /** * @see Anchor */ 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; @Override public int doEndTag() throws JspException { // 当前登录用户 User user = (User) pageContext.getSession().getAttribute("user"); // 当前准备显示的链接对应的权限URL // >> 在开头加上'/' String privUrl = "/" + action; if (user.hasPrivilegeByUrl(privUrl)) { return super.doEndTag(); // 正常的生成并显示超链接 标签,并继续执行页面中后面的代码 } else { return EVAL_PAGE; // 不生成与显示超链接 标签,只是继续执行页面中后面的代码 } } public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Anchor(stack, req, res); } protected void populateParams() { super.populateParams(); Anchor tag = (Anchor) component; tag.setHref(href); tag.setIncludeParams(includeParams); tag.setScheme(scheme); tag.setValue(value); tag.setMethod(method); tag.setNamespace(namespace); tag.setAction(action); tag.setPortletMode(portletMode); tag.setPortletUrlType(portletUrlType); tag.setWindowState(windowState); tag.setAnchor(anchor); if (encode != null) { tag.setEncode(Boolean.valueOf(encode).booleanValue()); } if (includeContext != null) { tag.setIncludeContext(Boolean.valueOf(includeContext).booleanValue()); } if (escapeAmp != null) { tag.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue()); } if (forceAddSchemeHostAndPort != null) { tag.setForceAddSchemeHostAndPort(Boolean.valueOf(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) { 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; } }
权限模块__使用权限__拦截验证每个请求的权限
两个问题:拦截器怎么写,往里边写权限判断
CheckPrivilegeInterceptor.java
public class CheckPrivilegeInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("-------------之前"); String result = invocation.invoke(); //放行 System.out.println("-------------之后"); return result; } }
struts.xml
<interceptors> <!-- 声明拦截器 --> <interceptor name="checkPrivilege" class="cn.itcast.oa.util.CheckPrivilegeInterceptor"></interceptor> <!-- 重新定义默认的拦截器栈 --> <interceptor-stack name="defaultStack"> <interceptor-ref name="checkPrivilege"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors>
另一种
说明拦截器可以用了,接着填充代码
struts.xml
<!-- 全局的Result配置 --> <global-results> <result name="loginUI">/WEB-INF/jsp/userAction/loginUI.jsp</result> <result name="noPrivilegeError">/noPrivilegeError.jsp</result> </global-results>
错误页面noPrivilegeError.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <HTML> <HEAD> <TITLE>没有权限</TITLE> <%@include file="/WEB-INF/jsp/public/commons.jspf" %> </HEAD> <BODY> <DIV ID="Title_bar"> <DIV ID="Title_bar_Head"> <DIV ID="Title_Head"></DIV> <DIV ID="Title"><!--页面标题--> <IMG BORDER="0" WIDTH="13" HEIGHT="13" SRC="${pageContext.request.contextPath}/style/images/title_arrow.gif"/> 提示 </DIV> <DIV ID="Title_End"></DIV> </DIV> </DIV> <!--显示表单内容--> <DIV ID="MainArea"> <DIV CLASS="ItemBlock_Title1"> </DIV> <DIV CLASS="ItemBlockBorder" STYLE="margin-left: 15px;"> <DIV CLASS="ItemBlock" STYLE="text-align: center; font-size: 16px;"> 出错了,您没有权限访问此功能! </DIV> </DIV> <!-- 操作 --> <DIV ID="InputDetailBar"> <A HREF="javascript:history.go(-1);"><IMG SRC="${pageContext.request.contextPath}/style/images/goBack.png"/></A> </DIV> </DIV> </BODY> </HTML>
CheckPrivilegeInterceptor.java
public class CheckPrivilegeInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { /*System.out.println("-------------之前"); String result = invocation.invoke(); //放行 System.out.println("-------------之后"); return result;*/ //获取信息 User user = (User) ActionContext.getContext().getSession().get("user");//当前的登录用户 String namespace = invocation.getProxy().getNamespace(); String actionName = invocation.getProxy().getActionName(); String privUrl = namespace + actionName;//对应的权限url //如果未登录 if(user == null) { if(privUrl.startsWith("/user_login")) { //如果是去登录,就放行 return invocation.invoke(); }else { //如果不是去登录,就转到登录页面 return "loginUI"; } } //如果已登录,就判断权限 else{ //如果有权限,就放行 if(user.hasPrivilegeByUrl(privUrl)) { return invocation.invoke(); } //如果没有权限,就转到提示页面 else{ return "noPrivilegeError"; } } } }
权限模块__使用权限__完善权限的分类
User.java
/** * 判定本用户是否有指定url的权限 * @param name * @return */ public boolean hasPrivilegeByUrl(String privUrl) { //超级管理员有所有的权限 if(ifAdmin()) { return true; } // >>去掉后面的参数 int pos = privUrl.indexOf("?"); if(pos > -1) { privUrl = privUrl.substring(0,pos); } // >>去掉UI后缀 if(privUrl.endsWith("UI")) { privUrl = privUrl.substring(0, privUrl.length() - 2); } //如果本URL不需要控制,则登录用户就可以使用 Collection<String> allPrivilegeUrls = (Collection<String>) ActionContext.getContext().getApplication().get("allPrivilegeUrls"); if(!allPrivilegeUrls.contains(privUrl)) { return true; }else{ //普通用户要判断是否含有这个权限 for(Role role : roles) { for(Privilege priv : role.getPrivileges()) { if(privUrl.equals(priv.getUrl())) { return true; } } } return false; } }
InitListener.java
//准备数据:allPrivilegeUrls Collection<String> allPrivilegeUrls = privilegeService.getAllPrivilegeUrls(); sce.getServletContext().setAttribute("allPrivilegeUrls", allPrivilegeUrls); System.out.println("-----------> 已准备数据 <-----------");
PrivilegeService.java
//查询所有权限对应的URL集合(不重复) Collection<String> getAllPrivilegeUrls();
PrivilegeServiceImpl.java
public Collection<String> getAllPrivilegeUrls() { return getSession().createQuery( "SELECT DISTINCT p.url FROM Privilege p WHERE p.url IS NOT NULL") .list(); }
需要处理的一些细节
权限模块__解决小问题:重启Tomcat后还是登录状态
用户关联的角色权限部门都实现序列化接口
implements Serializable
权限模块__解决小问题:登录页面嵌套的问题
最能让人感到快乐的事,莫过于经过一番努力后,所有东西正慢慢变成你想要的样子!