回顾之struts2拦截器

    很久没有做web项目了,最近公司要做个产品,目前正在做demo,暂时从大数据回归到web开发了,发现好多东西都忘光了,而且现在的web开发也比我做web的时候先进了许多,很多技术如雨后春笋般冒了出来,目前也在一点点的学习,在这之前我还是先回顾一下以前的知识点吧,毕竟太久没用真的生疏了,导致犯了很多低级错误,为了以后少犯这种错,写几篇小文章,梳理一下知识点。

    言归正传,这次回顾的是struts2拦截器。目前系统架构S2SH。首先引出几个名词。

    拦截器

    顾名思义,拦截器就是用来拦截的一个组件,在struts中拦截的访问action的请求。简单的说,在访问action之前,都会调用这个组件。利用这个特性,我们可以在拦截器中做很多事情,比如常说的表单校验,登录验证等。

    拦截器符合DRY(don’t repeat yourself)规则。早期的开发,由于经验缺乏等各种原因,开发人员经常会在很多很多不同的地方调用同样的方法,大部分人都是粘贴复制,这会对后期的维护工作带来巨大的隐患。而拦截器可以理解为调用方法的一种改进,因为拦截器可以在目标对象执行以前由系统自动执行,而调用方法则必须显示的调用才可以。这就使拦截器本身拥有更高层次的解耦性。

    拦截器栈

    拦截器栈就是将拦截器按照一定的顺序连接在一起的链,当满足拦截的要求时,则会按照实现声明的顺序依次执行拦截器。这使得我们可以处理较为复杂的情况。

    了解了这几个概念后,我们回顾一下在项目中如何使用拦截器,这里要展现的是自定义拦截器,一般真正的项目都会有自己特定的需求,很少用到struts自带或者默认的拦截器。

    首先,现在struts.xml中配置拦截器

    <package name="Global" extends="struts-default">
		<interceptors>  
            <!-- 定义拦截器 -->
			<interceptor name="loginInterceptor" class="commons.util.LoginInterceptor"></interceptor>  
			<!-- 定义拦截器栈 -->
            <interceptor-stack name="CENNAVIStack">
                <!-- 引用拦截器,在栈中,拦截器的先后顺序决定执行的顺序 -->
 				<interceptor-ref name="loginInterceptor"></interceptor-ref> 
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>  
		</interceptors>
        <!-- 将此拦截器栈设置成package全局拦截器,请求在此package下定义的action都会被拦截 -->  
		<default-interceptor-ref name="CENNAVIStack"></default-interceptor-ref>
        <!-- package全局result(global-results),如果action返回的string在自己的result中没有找到,就会查找这个全局的 -->
		<global-results>  
			<result name="login" type="redirect">login.html</result>
		</global-results>
	</package>
	
	<package name="Global-json" extends="json-default">
		<interceptors>  
			<interceptor name="loginInterceptor" class="commons.util.LoginInterceptor"></interceptor>  
			<interceptor-stack name="PBSStack">
 				<interceptor-ref name="loginInterceptor"></interceptor-ref> 
        		<interceptor-ref name="defaultStack" />
			</interceptor-stack>  
		</interceptors>  
		<default-interceptor-ref name="PBSStack"></default-interceptor-ref>
	</package>

    上面的配置均有注释,这里不细说,但要简单解释一下一个概念

  •     package

    从语义上讲,其实代表了每一个独立的模块。在这个模块中,你可以定义隶属于这个模块的行为方式,而与其他的模块没有关系。所以,每个package都有独立的interceptor、result-type和action的定义。

        name属性的值的package的名字,extends的值说明了继承哪个包

    其实可以把它看作为一个普通的java类的构造器,你所定义的拦截器、action,等等都是它的属性。而name就是这个类的对象名,extends就相当于这个类继承了哪个类。这样拦截器等等是这个对象的特有的属性,跟其他对象无关。

    再来看struts-default和json-default

    struts-default是struts-default.xml中定义的,而我们一般的配置文件都会继承这个配置文件。

    就拦截器而言,struts-default 包中预定义了很多拦截器,我们继承了这个包也就可以使用其中的拦截器。当然这个包中也定义了拦截器栈(interceptor-stack)以及默认使用的拦截器栈,默认使用的拦截器栈是defaultStack,内含18个顺序排列的拦截器。因此,如果自定义的package继承了struts-default而又没有任何拦截器上的修改,该自定义package使用的拦截器栈就是defaultStack。所以一般情况而言都会继承这个包。

    json-default

    struts2的json plugin可以实现struts2和json的完美结合,当我们要使用json 的时候就可以使用这个包。如果继承了这个包并且配置<result> 标签,如

<result type="json">
    <param name="root">list</param>
</result>

    而且在action中return了list,那么struts就可以将list这个对象自动转换为json格式数据,并返回给前端UI,不用我们再自己写转换了,极大程度的方便了开发。

    对于package,我们应该灵活运用,比如定义多个package,配置不同的拦截器,拦截特定的action,来达到特定的目的,比如权限和功能的控制等。

    上面你的配置配置了自定义的拦截器,接下来看看这个自定义拦截器如何写

package commons.util;

import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.struts2.ServletActionContext;
import com.cennavi.sys.hbm.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * 
 * @ClassName: LoginInterceptor 
 * @Description: TODO(这里用一句话描述这个类的作用) 
 * @author lzz 
 * @date 2017年3月1日 下午4:05:53 
 *
 */
public class LoginInterceptor extends AbstractInterceptor
{
	@Override
	public void init(){
        //应用启动的时候会先调用init方法
		System.out.println("init");
	}
	
	private static final long serialVersionUID = 2000108379092059226L;

	public String intercept(ActionInvocation invocation) throws Exception{
		System.out.println("intercept==================");
		Map session = ActionContext.getContext().getSession();
		HttpServletRequest request = ServletActionContext.getRequest(); 
		if(request.getRequestURI().indexOf(Commons.LOGIN_ACTION_URL) >= 1){
			return invocation.invoke();
		}
		
		User user = (User)session.get(Commons.USER_INFO);
		if(user != null) {
			return invocation.invoke();
		}
        return Action.LOGIN;			
	}
}

    上面代码只是一个示例,真正的系统中会有较多的逻辑,比如会有对ajax请求的处理等等。
   上面代码的功能是先判断是不是访问的登录的url,如果是则不拦截,直接调用登录url中的访问的action,如果不是登录的url,则获取session中的user,如果不为空,证明在登录的时候已经将这个user存放在session中,可以操作,如果为空,则需要重新登录。其中Action.LOGIN所对应的字符串是“login”,之前我们在struts.xml中有配置

<global-results>  
    <result name="login" type="redirect">login.html</result>
</global-results>

    Action.LOGIN所对应的就是这个配置,一但拦截器返回login,则重定向login.html

    当然在这个拦截器中还可以做其他的事情,比如权限的进一步验证等,看个人需求。

    到这,基本上把拦截器的知识简单的回顾了。

 

转载于:https://my.oschina.net/U74F1zkKW/blog/891980

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Struts2 中,可以使用拦截器来实现权限控制。具体来说,可以编写一个自定义的拦截器,然后在 struts.xml 配置文件中将其配置为需要进行权限控制的 Action 的拦截器。以下是一个简单的权限拦截器示例: ```java public class AuthInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // 获取当前用户 User user = (User) ActionContext.getContext().getSession().get("user"); // 判断用户是否拥有权限 if (user != null && user.hasPermission(invocation.getInvocationContext().getName())) { // 如果有权限,则继续执行 Action return invocation.invoke(); } else { // 如果没有权限,则跳转到错误页面 return "error"; } } } ``` 在上述代码中,我们首先获取了当前用户,然后判断用户是否拥有执行当前 Action 的权限。如果有权限,则继续执行 Action;否则,跳转到错误页面。 接下来,在 struts.xml 配置文件中,我们可以将该拦截器配置为需要进行权限控制的 Action 的拦截器,如下所示: ```xml <action name="myAction" class="com.example.MyAction"> <interceptor-ref name="authInterceptor"/> <result name="success">/myAction.jsp</result> <result name="error">/error.jsp</result> </action> <interceptor-stack name="authStack"> <interceptor-ref name="authInterceptor"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> <interceptors> <interceptor name="authInterceptor" class="com.example.AuthInterceptor"/> </interceptors> ``` 在上述代码中,我们首先定义了一个名为 authStack 的拦截器栈,该拦截器栈包含了 authInterceptor 和 defaultStack 两个拦截器。然后,我们将 myAction Action 配置为使用 authStack 拦截器栈。最后,我们定义了一个名为 authInterceptor 的拦截器,并将其添加到了 interceptors 中。 这样一来,当用户访问 myAction Action 时,就会先执行 authInterceptor 拦截器,进行权限控制,然后再执行 defaultStack 拦截器栈中的其它拦截器。如果 authInterceptor 拦截器返回了 error,则会跳转到 error.jsp 页面;否则,会跳转到 myAction.jsp 页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值