0.需求
如何讓用戶在瀏覽器地址欄鍵入[http://XXX.XXX.XX.XX:端口號/應用名/]以后自動跳轉到系統的登錄界面
1.web.xml
1.1 注意welcome-file-list的配置,將welcome-file賦值為"/"
1.2 springmvc 的 dispatcherServlet的url-pattern是"/"
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>leslie</display-name> <welcome-file-list> <welcome-file>/</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mybatis.xml,/WEB-INF/leslie-dispatcher-servlet.xml,/WEB-INF/applicationContext-timertask.xml </param-value> </context-param> <!-- 編碼過濾器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 防止Spring內存溢出監聽器 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <servlet> <servlet-name>leslie-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>leslie-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>logbackConfigLocation</param-name> <param-value>classpath:logback.xml</param-value> </context-param> <listener> <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class> </listener> <context-param> <param-name>spring.profiles.active</param-name> <param-value>dev</param-value> </context-param> <context-param> <param-name>spring.profiles.default</param-name> <param-value>dev</param-value> </context-param> <context-param> <param-name>spring.liveBeansView.mbeanDomain</param-name> <param-value>dev</param-value> </context-param> </web-app>
2.dispatcherServlet配置文件
2.1 注意我配置了一個判斷用戶是否登錄的攔截器
<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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" 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 http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <context:component-scan base-package="com.leslie" /> <mvc:annotation-driven /> <!--url攔截器,對指定的Url進行攔截,判斷Session中是否存在用戶信息,防止用戶通過直接輸入url的方式越級訪問 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.leslie.interceptor.UserLoginInterceptor" /> </mvc:interceptor> </mvc:interceptors> <!--國際化property文件 --> <!-- <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:/messages/messages</value> </list> </property> <property name="useCodeAsDefaultMessage" value="true" /> </bean> --> <!--避免IE執行AJAX時,返回JSON出現下載文件 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <!-- 啟動SpringMVC的注解功能,完成請求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON轉換器 --> </list> </property> </bean> <!-- 定義跳轉的文件的前后綴 ,視圖模式配置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 配置文件上傳,如果沒有使用文件上傳可以不用配置,當然如果不配,那么配置文件中也不必引入上傳組件包 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 默認編碼 --> <property name="defaultEncoding" value="utf-8" /> <!-- 文件大小最大值 --> <property name="maxUploadSize" value="10485760000" /> <!-- 內存中的最大值 --> <property name="maxInMemorySize" value="40960" /> </bean> </beans>
2.2 攔截器的實現代碼
2.2.1 字符串數組IGNORE_URI定義了攔截器不攔截的uri,包括用戶登錄界面以及check用戶登錄信息兩個邏輯是不攔截的。
preHandle方法在執行controller之前被執行,主要的邏輯是首先看當前url是不是在IGNORE_URI中定義的,
如果是就放行,返回true。如果不是,就從session里取用戶登錄信息,如果取到了用戶對象則視為用戶已經登錄,那么放行,返回true。否則,視為用戶未登錄,不放行,返回false。
2.2.2 我們的目的是讓攔截器為"/"放行,但我們不能將"/"配置到IGNORE_URI里,因為"/"表示任意的url-pattern,這樣攔截器勢必會對所有的url放行,失去了
攔截的意義。所以就有了requestUrl.endsWith(applicationName)這個邏輯,也就是手動判斷當前url是不是[http://XXX.XXX.XX.XX:端口號/應用名/]風格的,如果是就放行。
package com.leslie.interceptor; import java.io.File; import javax.interceptor.Interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.leslie.controller.SJLoginController; import com.leslie.model.User; /** * 登錄攔截器 * * */ @Interceptor public class UserLoginInterceptor extends HandlerInterceptorAdapter { private static final String[] IGNORE_URI = { "/loginPage", "/checkLogin", "/hello" }; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String applicationName = "/" + request.getContextPath().split("/")[request.getContextPath().split("/").length - 1] + "/"; String requestUrl = request.getRequestURL().toString(); if (requestUrl.endsWith(applicationName)) { return true; } boolean flag = false; String url = request.getRequestURL().toString(); for (String s : IGNORE_URI) { if (url.contains(s)) { flag = true; break; } } if (!flag) { User user = SJLoginController.getLoginUser(request); if (user != null) { // List<String> urls = // SJLoginController.getUserRoleUrls(request); // if(urls.contains(url)){ // flag = true; // } flag = true; } } return flag; } }
3.為歡迎頁面單獨分配一個controller
3.1 使用forward將頁面跳轉到兄弟controller,在這里是用戶登錄controller的打開登錄頁面url
package com.leslie.util; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class SJWelcomeController { @RequestMapping("/") public String welcome(){ return "forward:/login/loginPage"; } }