struts2中的拦截器问题

大多数的web端项目都会用到"权限"这个东西,首先要明白权限是捆绑在角色上的,也就是对应关系,权限:角色=n:1.

既然需要有权限的地方,那么拦截器自然不可以缺少了。

1.拦截器的配置文件(struts.xml):

<package name="manage" namespace="/" extends="default">
	<!--管理员 -->
<interceptors>
        <interceptor name="admininter" class="cn.yitongworld.util.AdminInteceptor"></interceptor>	        <interceptor-stack name="admininterstack">
			<interceptor-ref name="defaultStack"></interceptor-ref>
			<interceptor-ref name="admininter"></interceptor-ref>
			</interceptor-stack> 
		</interceptors>
	<!-- 配置默认拦截器栈-->
<default-interceptor-ref name="admininterstack"/>
	 <global-results>
		<result name="login" type="chain">preLogin</result>
		<result name="optresult_success">/WEB-INF/manage/operationresult_success.jsp</result>
		<result name="optresult_error">/WEB-INF/manage/operationresult_error.jsp</result>
		</global-results>
	<!-- 上传图片 -->
<action name="fileUpload" class="cn.yitongworld.action.FileUploadAction"></action>
</package>

2.java代码(类):

@ParentPackage("manage")
@Namespace("/")
@Controller
public class ManBillAction extends BaseAction<Bill> {

	代码省略.........

}

3.java代码(拦截器)

@SuppressWarnings("serial")
public class AdminInteceptor extends AbstractInterceptor {
	@Override
	public String intercept(ActionInvocation invocation){
	//获取当前用户信息
	Map<String, Object> session = ActionContext.getContext().getSession();
	//获得当前请求的对象(好像就是一个地址)
	HttpServletRequest request = ServletActionContext.getRequest();
	     //判断用户是否存在
	     if(session.get(Const.SESS_USER)!=null){
	    	 try {    //转换称用户对象
		    	 User user=(User) session.get(Const.SESS_USER);
		    	 //判断用户是不是管理员
		    	 if(user.getId()==null||!user.getType().equals(UserType.ADMINUSER)){
		    	 		
		    	 		return Action.LOGIN;
		    	 	}
		    	 //判断用户是不是超级管理员
		    	 if(user.getId().toString().equals(Cache.getSetting(Const.SUPERADINID).getValue())){                  //如果是超级管理员,继续调用下面的action或者是result       
		    	 return invocation.invoke();
		    	 	}
		    	 //判断用户的权限和角色是否为空
		    	 if(MyString.isEmpty(user.getAuthority())&&MyString.isEmpty(user.getRole())){
		    	 		request.setAttribute("tipMessage","抱歉,权限不够!");
		    	 		return Action.ERROR;
		    	 	}
		    	 //从当前请求的对象中得到url
		    	 String url=request.getRequestURI();
		    	 //从url中截取出action
			 String action =url.substring(url.lastIndexOf("/")+1);
			 //判断是否含有权限
		    	 if(hasAuth(invocation, user.getAuthority(), action))
		    	        //如果有权限继续走原先的action
		    	 	return invocation.invoke();
		    	 //判断所在角色是否含有权限
		    	 if(!MyString.isEmpty(user.getRole()))
		    	         //角色有多个权限
		    	         for(String role:user.getRole().split(",")){
		    	             //role其实就是角色中的任意一个权限
		    	 	    if(hasAuth(invocation, StaticDataCache.getStaticdata(role).getValue(), action))                               //如果有权限继续走原先的action
				    	    return invocation.invoke();
		    	 		}
		    	 	request.setAttribute("tipMessage","抱歉,权限不够!");
	    	 		return Action.ERROR;
				} catch (Exception e) {
					e.printStackTrace();
					return "500"; 
				}
	     }else{
	    	 request.setAttribute("tipMessage","未登陆,请先登陆!");
	    	 //跳转至拦截页面
	    	 if(!request.getRequestURI().contains("login"))
	    		 session.put("returnUrl", getReturnUrl(request));
	    	 return Action.LOGIN;  
		}
		
	}
	private boolean hasAuth(ActionInvocation invocation, String authority, String action){
		if(!MyString.isEmpty(authority)){
			for(String auth:authority.split(","))
			{
				if(MyString.isEmpty(auth)){
					continue;
				}
				try{
					Staticdata sd = StaticDataCache.getStaticdata(auth.trim());
					if(sd.getValue()==null)
						continue;
					if(sd.getValue().equals(action))
						return true;
				}catch(Exception e){
					e.printStackTrace();
					continue;
				}
			}
		}
		return false;
	}
	private String getReturnUrl(HttpServletRequest request){
		Map<String, String[]> map=request.getParameterMap();
		StringBuffer temp=new StringBuffer(request.getRequestURI()+"?");
		Iterator<Entry<String, String[]>> iter = map.entrySet().iterator();
		while (iter.hasNext()) {
		   Map.Entry<String, String[]> entry = (Map.Entry<String, String[]>) iter.next();
		   for(String val:entry.getValue()){
			   temp.append(entry.getKey()+"="+val+"&");
		   }
		}
		String value=temp.toString();
		if(value.endsWith("&")){
			value=value.substring(0, value.length()-1);
		}
		return temp.toString();
	}

}

程序应该是这样走的,当用户点击相应的url的时候,会直接进入action中,但是在action中出现了以下2个注解

@ParentPackage("manage")
@Namespace("/")

你是不是想问这个是什么呢?看完拦截器的配置你就懂了,是对应的(此拦截器配置在了进入action之前)

<package name="manage" namespace="/" extends="default">

所以说还没有加载页面数据的时候,程序看到类的注释会先去配置文件中找到相应的Interceptor

<interceptor name="admininter" class="cn.yitongworld.util.AdminInteceptor"></interceptor>

根据Interceptor的引用找到相应的类进行拦截,直到遇见

return invocation.invoke();

说明拦截成功,此时程序会怎么样执行呢?也是最难的一点对于我这个菜鸟来说。一般来说都是调用一个方法得到一个结果,那拦截器是不是这个道理呢?当然啦!说明拦截成功了!只有拦截成功才可以运行下面的"程序",这个"程序"指的就是加拦截器注释的类。大概程序运行过程是这样的:2->1->3->2

总结:struts2的Interceptor其实有n种方式去拦截,我这里是在程序执行之前进行的拦截(用户没有权限直接不去执行下面的action),你也可以在加载页面数据之后进行CRUD的拦截。根据具体情况而定了。

你可能感兴趣的:(struts2,权限,角色,Invoke(),Intercaptor)