SpringMVC使用攔截器實現許可權控制

程式界小強發表於2015-06-26

1、首先準備對應的架包

2、看看專案的架構

3、基本的web.xml檔案

<!--?xml version="1.0" encoding="UTF-8"?-->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>shiro</display-name>
 
    <!-- 載入springmvc -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <!-- 以.htm結尾的都被mvc攔截 -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
     
    <!-- 啟動spring 載入   需要載入其他的spring時 需啟動該監聽器
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
     -->
</web-app>

4、配置classpath下的mvc.xml檔案

<!--?xml version="1.0" encoding="UTF-8"?-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd 
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <mvc:annotation-driven>
    <!-- 自動掃描包 -->
    <context:component-scan base-package="com.cat.spring.controller">
 
    <!--  配置mvc的攔截器 可以配置多個 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--  需要被攔截的路徑 -->
            <mvc:mapping path="/member/**">
            <!-- 攔截處理的interceptor -->
            <bean class="com.cat.interceptor.MemberInterceptor">
        </bean></mvc:mapping></mvc:interceptor>
    </mvc:interceptors>
 
    <!-- mvc返回頁面的配置 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <!-- 模板路徑為WEB-INF/pages/ -->
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <!-- 檢視模板字尾為.JSP -->
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
 
</context:component-scan></mvc:annotation-driven></beans>

5、接著就要配置攔截器了MemberInterceptor.java

/**
 * 
 */
package com.cat.interceptor;
 
import java.net.URLEncoder;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
/**
 * @author chenlf
 * 
 *         2014-3-25
 */
public class MemberInterceptor implements HandlerInterceptor {
 
    public final static String SEESION_MEMBER = "seesion_member";
 
    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax.servlet.http.HttpServletRequest,
     * javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
     */
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
            Exception arg3) throws Exception {
        // TODO Auto-generated method stub
 
    }
 
    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.servlet.http.HttpServletRequest,
     * javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
     */
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
            ModelAndView arg3) throws Exception {
        // TODO Auto-generated method stub
 
    }
 
    /*
     * (non-Javadoc)
     * 攔截mvc.xml配置的/member/**路徑的請求
     * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest,
     * javax.servlet.http.HttpServletResponse, java.lang.Object)
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) throws Exception {
        //請求的路徑
        String contextPath=request.getContextPath();
        String  url=request.getServletPath().toString();
        HttpSession session = request.getSession();
        String user = (String) session.getAttribute(SEESION_MEMBER);
        //這裡可以根據session的使用者來判斷角色的許可權,根據許可權來重定向不同的頁面,簡單起見,這裡只是做了一個重定向
        if (StringUtils.isEmpty(user)) {
            //被攔截,重定向到login介面
            response.sendRedirect(contextPath+"/login.htm?redirectURL="
                    + URLEncoder.encode(url));
            return false;
        }
        return true;
    }
 
}

這樣攔截器的核心就配置完了,接下來就是一些登陸的處理操作

6、LoginController.java檔案

package com.cat.spring.controller;
 
import java.net.URLDecoder;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
 
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
 
import com.cat.interceptor.MemberInterceptor;
 
/**
 * @author chenlf
 * 
 *         2014-3-24
 */
@Controller
public class LoginController {
 
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ModelAndView login(String redirectURL, HttpServletRequest request) {
        ModelAndView view = new ModelAndView();
        //把攔截前路徑存下來,以便登入成功可以直接請求到登入前的頁面
        view.addObject("redirectURL", redirectURL);
        view.setViewName("/login");
        return view;
    }
 
    @RequestMapping(value = "/submit", method = RequestMethod.POST)
    public String submit(String username, String password, String redirectURL,
            HttpServletRequest request) {
        //模擬登陸成功 使用者admin 密碼admin的使用者
        if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)
                && username.equals("admin") && password.equals("admin")) {
            //當登陸成功是,將使用者資訊存放到session中去
            HttpSession session = request.getSession();
            session.setAttribute(MemberInterceptor.SEESION_MEMBER, "admin");
            if (StringUtils.isNotBlank(redirectURL)) {
                return "redirect:" + URLDecoder.decode(redirectURL);
            }
            return "redirect:/member/index.htm";
        } else {
            if (StringUtils.isNotBlank(redirectURL)) {
                return "redirect:/login.htm?" + URLDecoder.decode(redirectURL);
            }
            return "redirect:/login.htm";
        }
    }

7、下面就是login.jsp檔案

<%@ page language="java"
contentType="text/html; charset=UTF-8"
    pageEncoding="utf-8"%>

8、到這裡看看效果吧

a、當非登陸狀態的時候,請求localhost:8010/demo-mvc/member/list.htm時,被攔截攔截,重定向到login頁面,並攜帶了當前的這個路徑(/member/list.htm)作為引數傳到頁面

b、輸入正確的使用者名稱admin 密碼admin後登陸,會跳轉到攔截前的頁面

c、當登陸完成後,輸入地址為http://localhost:8010/demo-mvc/member/index.htm,session中記錄著當前使用者的資訊,不需要重新登陸了


相關文章