1. 程式人生 > >用Cookie實現使用者免密登陸

用Cookie實現使用者免密登陸

1.導jar包

pom.xml

 <properties>
  <!-- spring 版本號 -->
  <spring.version>4.3.8.RELEASE</spring.version>
 </properties>
<!-- AOP相關包 -->
<dependency>
        <groupId>aspectj</groupId>
    	<artifactId>aspectjrt</artifactId>
    	<version>1.5.3</version>
</dependency>
<dependency>
        <groupId>org.aspectj</groupId>
    	<artifactId>aspectjweaver</artifactId>
    	<version>1.8.0</version>
</dependency>
<dependency>
   	<groupId>cglib</groupId>
   	<artifactId>cglib-nodep</artifactId>
   	<version>2.1_3</version>
</dependency>

<dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-aop</artifactId>
       <version>${spring.version}</version>
</dependency>
        
<dependency>
    	<groupId>org.springframework</groupId>
    	<artifactId>spring-aspects</artifactId>
    	<version>${spring.version}</version>
</dependency>

web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
       version="3.1" metadata-complete="true">
        
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            classpath*:/spring-mybatis.xml,
        	classpath*:/spring-tx.xml
    </param-value>
  </context-param>
   
   <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener </listener-class>
  </listener>	
   <servlet>
    <servlet-name>springServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
   
  <servlet-mapping>
    <servlet-name>springServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
 <!-- 指定監聽器載入的log4j配置檔案 -->
	<context-param>  
        <param-name>log4jConfigLocation</param-name>  
        <param-value>classpath:log4j.properties</param-value>  
	</context-param>  
	<listener>  
        <listener-class>  
            org.springframework.web.util.Log4jConfigListener  
        </listener-class>  
    </listener>

  <session-config>
    <session-timeout>20</session-timeout>
  </session-config>   
  
</web-app>

spring-mybatis.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:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
 
 	<!--讀取配置檔案-->
    <!-- <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:db.properties</value>
            </list>
        </property>
    </bean> -->
	<context:property-placeholder location="classpath:db.properties"
                                  ignore-unresolvable="false" />
    <!-- 定義資料來源Bean -->
    <!-- Druid -->
    <!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    	init-method="init" destroy-method="close">
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
    </bean> --> 
 
 	<!-- 配置資料來源 -->
 	<bean id="dataSource"
	class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="singleton">
	<property name="driverClassName" value="${jdbc.driver}"/>
	<property name="url" value="${jdbc.url}"/>
	<property name="username" value="${jdbc.username}"/>
	<property name="password" value="${jdbc.password}"/>
	</bean> 
	
    <!-- 註冊SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自動掃描mappers.xml檔案 -->
        <property name="mapperLocations" value="classpath:top/lolcl/myblog/dao/*.xml" />
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    </bean>
    
    <!-- DAO介面所在包名,Spring會自動查詢其下的類 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="top.lolcl.myblog.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
</beans>



spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
 
    <!-- 啟動自動掃描 -->
    <context:component-scan base-package="top.lolcl.myblog" /> 
 
    <!-- 註冊MVC註解驅動 -->
    <mvc:annotation-driven />
	
    <!-- 靜態資源可訪問的設定方式 -->
    <mvc:default-servlet-handler />
    
    <!-- 開啟AOP註解掃描 -->
    <aop:aspectj-autoproxy proxy-target-class="true" />
    
     <!-- 強制使用cglib代理,如果不設定,將預設使用jdk代理,但是jdk的代理是基於介面的 -->
    <aop:config proxy-target-class="true" />
 
    <!-- 配置檢視解析器,可以顯式設定,也可以不設定,不設定會依據SpringMVC的預設設定 -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

spring-tx.xml

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 宣告式事務 , 使用註解方式進行事務控制 -->
   <tx:annotation-driven transaction-manager="txManager"/> 

cookie工具類

package top.lolcl.myblog.util;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * cookie工具類 獲取 設定cookie
 * @author sanch
 *
 */
public class CookieUtil {
	/**
	 * 設定Cookie
	 * @param request
	 * @param response
	 * @param value
	 * @param mavAge
	 */
	public static void addCookie(HttpServletResponse response, String name , String value,int maxAge) {
		Cookie cookie = new Cookie(name,value);
		cookie.setPath("/");
		if(maxAge > 0) {
			cookie.setMaxAge(maxAge);  //退出頁面 cookie 預設值-1
		}
		response.addCookie(cookie);
	}
	
	/**
	 * 根據名字獲取cookie
	 * @param name
	 * @return
	 */
	public static Cookie getCookieByName(HttpServletRequest request,String name) {
		Map<String,Cookie> cookieMap = ReadCookieMap(request);
		if(cookieMap.containsKey(name)) {
			Cookie cookie = cookieMap.get(name);
			return cookie;
		}else {
			return null;
		}
	}

	/**
	 * 將cookie封裝到map裡面
	 * @param request
	 * @return
	 */
	private static Map<String, Cookie> ReadCookieMap(HttpServletRequest request) {
		Map<String , Cookie> cookieMap = new HashMap<String , Cookie>();
		Cookie[] cookies = request.getCookies();
		if(null != cookies) {
			for(Cookie cookie : cookies) {
				cookieMap.put(cookie.getName(), cookie);
			}
		}
		return cookieMap;
	}

}

user使用者的Controller程式碼

@Transactional
	@RequestMapping(value="/login",method=RequestMethod.POST)
	public ModelAndView login(User model,HttpServletRequest request,HttpServletResponse response) throws Exception {
		logger.info("login-----------------------------------------------");
		User user = null;
		user = userservice.getUserByUname(model.getUname());
//		userservice.insertSelective(model);
//		int d = 1/0; //可以控制事務
		  
		if(user == null || !user.getUpwd().equals(MyMD5Util.MD5(model.getUpwd()))) {
			Map<String,String> map = new HashMap<String,String>();
//			request.setAttribute("msg", "使用者名稱密碼輸入錯誤,請重新輸入");
			ModelAndView mod = new ModelAndView("forward:/user/view"); //redirect:重定向不能攜帶引數值進行傳遞  forward:轉發可以帶參
			mod.addObject("msg", "使用者名稱密碼輸入錯誤,請重新輸入"); //瀏覽器如果關閉預設cookie值為-1 所以需要設定cookie的有效時間
			return mod;
		}else {
			request.getSession().setAttribute("user", user);
			//寫cookie 使用者免登陸
			CookieUtil.addCookie(response, "user", user.getUname(), Constants.COOKIE_AGE);
			
			return new ModelAndView("redirect:/user/index");
		}
	}

spring aop  使用註解的方式進行切面程式設計 方法前置處理

package top.lolcl.myblog.interceptor;

import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import top.lolcl.myblog.entity.User;
import top.lolcl.myblog.service.IUserService;
import top.lolcl.myblog.util.CookieUtil;

/**
 * log日誌攔截器
 * @author sanch
 *
 */
@Aspect // 表示該類是一個通知類
@Component //spring註解方式bean注入 交給spring管理
public class LogInterceptor {
	
	private  final static Logger logger = Logger.getLogger(LogInterceptor.class);
	
	@Autowired
	private IUserService userservice;
	//定義一個空方法 借用其註解抽取切點表示式
	@Pointcut("execution (* top.lolcl.myblog.controller.*.*(..))")
	public void pc() {}
	
	//前置通知
	@Before("pc()")
	public void before(JoinPoint joinPoint) throws Exception{
		System.out.println("login start!================================================================================");
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(requestAttributes.REFERENCE_REQUEST);
		Cookie cookie = CookieUtil.getCookieByName(request,"user");
		if(cookie != null && cookie.getValue() != "") {
			User user = userservice.getUserByUname(cookie.getValue());
			if(user != null) {
				request.getSession().setAttribute("user", user);
			}
			
		}
		logger.info("login start!================================================================================");
	}
	
	//後置通知
	@After("pc()")
	public void after(JoinPoint joinPoint) {
		System.out.println("login end=====================================================================================");
		logger.info("login end=====================================================================================");
	}
}