web技术回顾之struts2拦截器

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

  言归正传,此次回顾的是struts2拦截器。固然如今web技术已经基本不用struts了,这里介绍仍是但愿能多多关注拦截器自己。因此首先引出几个名词。前端

拦截器

  顾名思义,拦截器就是用来拦截的一个组件,在struts中拦截的访问action的请求。简单的说,在访问action以前,都会调用这个组件。利用这个特性,咱们能够在拦截器中作不少事情,好比常说的表单校验,登陆验证等。java

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

拦截器栈

  拦截器栈就是将拦截器按照必定的顺序链接在一块儿的链,当知足拦截的要求时,则会按照实现声明的顺序依次执行拦截器。这使得咱们能够处理较为复杂的状况。ajax

  了解了这几个概念后,咱们回顾一下在项目中如何使用拦截器,这里要展示的是自定义拦截器,通常真正的项目都会有本身特定的需求,不多用到struts自带或者默认的拦截器。apache

  首先,如今struts.xml中配置拦截器json

<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>

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

package

  从语义上讲,其实表明了每个独立的模块。在这个模块中,你能够定义隶属于这个模块的行为方式,而与其余的模块没有关系。因此,每一个package都有独立的interceptor、result-type和action的定义。ide

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

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

再来看struts-default和json-default

struts-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

  固然在这个拦截器中还能够作其余的事情,好比权限的进一步验证等,看我的需求。

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

相关文章
相关标签/搜索