基于SSH实现员工管理系统登录权限的过滤器与拦截器的综合使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Stephen__Xu/article/details/78312536

需要实现的功能:判断用户是否已登录,未登录用户禁止访问任何页面或action,自动跳转到登录页面。

过程很艰辛,虽然是挺简单的应用,但是自己也弄了好久才有些许弄明白,结合网上搜索到的内容写下这篇总结,待日后可回头查看。
刚开始是先搜了拦截器如何拦截未登录用户的操作的,正是初生牛犊不怕虎,找到一篇文章就死怼,怼到后面发现不大对,虽然action是拦截掉了,但是jsp怎么样都拦截不到,直接输入.jsp的url还是能访问到网页。苦思冥想,想不出如何做才行。后面发现拦截器本就不能拦截jsp页面、图片等其他资源,拦截器由spring管理,只对action起作用。
于是搜索过滤器的内容,发现过滤器则能过滤所有内容,过滤器的范围要大于拦截器。那就把两者结合起来用吧,反正拦截器已写好,只需写过滤jsp页面的过滤器即可。

过滤器filter实现:
配置web.xml

<filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>xu.ssh.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

代码:

package xu.ssh.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import xu.ssh.domain.Employee;

public class LoginFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        // 获得在下面代码中要用的request,response,session对象
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        HttpSession session = servletRequest.getSession();

        // 获得用户请求的URI
        String path = servletRequest.getRequestURI();
        // System.out.println(path);

        // 从session里取员工工号信息
        Employee employee = (Employee) session.getAttribute("existEmployee");

        /*
         * 创建类Constants.java,里面写的是无需过滤的页面 for (int i = 0; i <
         * Constants.NoFilter_Pages.length; i++) { if
         * (path.indexOf(Constants.NoFilter_Pages[i]) > -1) {
         * chain.doFilter(servletRequest, servletResponse); return; } }
         */

        // 登陆页面无需过滤
        if (path.indexOf("/login.jsp") > -1) {
            chain.doFilter(servletRequest, servletResponse);
            return;
        }

        // 判断如果没有取到员工信息,就跳转到登陆页面
        if ("".equals(employee) || employee == null) {
            // 跳转到登陆页面
            servletResponse.sendRedirect("/ssh_employee/login.jsp");
        } else {
            // 已经登陆,继续此次请求
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }

}

配置中的filter-mapping,定义的是需过滤的请求类型,上面的配置即过滤所有对jsp页面的请求。过滤器的实现与struts2、spring框架无关,在用户请求被相应前执行,在过滤器中,可使用response.sendRedirect(“”)等方法
跳转到需要的链接,如登录页面、错误页面等,不需要跳转时,chain.doFilter(request, response);即可继续执行用户的请求。注意使用filter时避免连续两次跳转,否则会报java.lang.IllegalStateException错误,除非必要,不建议使用/*(过滤所有访问)的配置方式,这样配置,图片、js文件、css文件等访问都会被过滤

拦截器interceptor实现:
配置:struts.xml

<!-- 拦截器 --> 
        <interceptors>
            <interceptor name="myInterceptor" class="xu.ssh.action.MyInterceptor"></interceptor>
            <interceptor-stack name="myInterceptor">
                <interceptor-ref name="myInterceptor">
                    <param name="excludeMethods">login</param><!-- 不拦截的方法-->
                </interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 将上述拦截器设定为默认拦截器 ,这样在后续同一个package内部的所有Action执行之前都会被login拦截。-->
        <default-interceptor-ref name="myInterceptor" /> 

代码:

package xu.ssh.action;

import org.apache.struts2.ServletActionContext;

import xu.ssh.domain.Employee;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class MyInterceptor extends MethodFilterInterceptor{

    /**
     * @param args
     */

    @Override
    protected String doIntercept(ActionInvocation actionInvocation) throws Exception {

        Employee employee = (Employee) ServletActionContext.getRequest().getSession().getAttribute("existEmployee");

        if(employee!=null){
            // is logined ,have the userinfo in the session  
            return actionInvocation.invoke();//递归调用拦截器
        }else{
            //is not logged
            ActionSupport support = (ActionSupport) actionInvocation.getAction();
            support.addActionError("请先登录:)");
            return "loginfail";//返回到登录页面
        }

    }

}

拦截器截获用户对action的访问,如需要跳转,只需如action一样返回一个result,spring根据result的配置执行跳转。如无需跳转,可调用invocation.invoke();方法来执行用户请求的action。拦截器在action之前开始,在action完成后结束(如被拦截,action根本不执行)

参考博客
参考文档

猜你喜欢

转载自blog.csdn.net/Stephen__Xu/article/details/78312536