现在的位置: 首页 > 综合 > 正文

有关采用Filter:实现网站自动登录功能模块

2014年01月19日 ⁄ 综合 ⁄ 共 12577字 ⁄ 字号 评论关闭

网站自动登录操作分析,我以CSDN用户登录功能为例说明,

   1.进入csdn网站的登录界面 地址: CSDN用户登录界面   界面效果如下:

      

     2.输入正确的用户名和密码,并且勾选上 下次自动登录功能

     

       3.点击登录,如果成功登录,就会跳转到登陆成功的界面.

       4.如果你再去点击CSDN用户登录界面 看看什么效果,你会发现,打不开此登录界面,直接跳转到了如下图界面:

       

 

        5.可以看到此时,已经完成了自动登录的功能模块.

根据以上分析,我结合Java Web中的Filter和Cookie完成一个网站自动登录的功能模块.

1.编写登录界面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
   
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
	
  </head>
  
  <body>
     ${requestScope.msg}<br/>
      <form action="${pageContext.request.contextPath}/AdminOper.do" method="post">
        <table>
           <tr>
             <td>用户名:</td>
             <td><input type="text" name="name"/></td>
           </tr>
           <tr>
             <td>密码:</td>
             <td><input type="password" name="pass"/></td>
           </tr>
           <tr>
             <td colspan="2">
               <input type="radio" name="day" checked="checked" value="7">一周
               <input type="radio" name="day" value="30">一月
               <input type="radio" name="day" value="90">三个月
             </td>
           </tr>
           <tr>
             <td><input type="checkbox" name="mark" value="mark"/></td>
             <td>下次自动登陆</td>
           </tr>
           <tr>
             <td> <input type="submit" value="登陆"/></td>
             <td><input type="reset"  value="重置"/></td>
           </tr>
        </table>
         <input type="hidden" name="oper" value="login"/>
      </form>
  </body>
</html>

效果如下:

  

2.登录界面处理的servlet类.

package www.csdn.net.day56.servlet;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

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

import sun.misc.BASE64Encoder;

import com.sun.mail.util.BASE64EncoderStream;

import www.csdn.net.day56.bean.Admin;
import www.csdn.net.day56.dao.AdminDao;
import www.csdn.net.day56.dao.impl.AdminDaoImpl;
import www.csdn.net.day56.service.AdminService;
import www.csdn.net.day56.service.impl.AdminServiceImpl;

public class AdminServlet extends HttpServlet {

	private AdminService adminService = new AdminServiceImpl();

	private long expires = 24 * 60 * 60; // 1天

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String method = request.getMethod();
		System.out.println("请求的方法::::" + method);
		// 获取请求参数中 操作的标识符
		String oper = request.getParameter("oper");

		if ("login".equals(oper)) {
			// 处理登陆
			// 获取用户名和密码
			String name = request.getParameter("name");
			String pass = request.getParameter("pass");
			//获取标记 是否自动登录标识符
			String mark = request.getParameter("mark");

			// 验证用户名和密码是否正确
			Admin entity = adminService.checkLogin(name, pass);

			if (entity != null) {
				// 判断是自动登录处理
				if ("mark".equals(mark)) {
					// 获取默认记住的天数
					String day = request.getParameter("day");
					// 转换成有效的时间
					expires = Integer.valueOf(day) * expires;
					// 声明cookie
					Cookie autoCookie = null;
					// 获取所有cookie
					Cookie cookies[] = request.getCookies();
					// 遍历cookie
					for (Cookie cookie : cookies) {
						// 判断是否存在自动登陆记录
						if ("autologin".equals(cookie.getName())) {
							autoCookie = cookie; // 赋值

							// 当cookie存在的时候,我需要重新设置值
							long time = (System.currentTimeMillis() + expires * 1000);
						    //cookie拼接的value值,(可以根据自己的想法设计)
							String newValue = name + ":" + time + ":"
									+ md5Value(name + ":" + pass + ":" + time);
							//设置值
							autoCookie .setValue(newValue);
						} else {
							// 不存在创建
							// name+":"+time+":"+md5(name:pass:time)
							long time = System.currentTimeMillis() + expires
									* 1000;
							//cookie拼接的value值,(可以根据自己的想法设计)
							String cookieValue = name + ":" + time + ":"
									+ md5Value(name + ":" + pass + ":" + time);
							//创建cookie
							autoCookie = new Cookie("autologin", cookieValue);
						}
					}

					autoCookie.setMaxAge((int) expires);
					autoCookie.setPath("/day56");
					// 添加cookie
					response.addCookie(autoCookie);

				}
				// admin存入到session
				request.getSession().setAttribute("admin", entity);
				// 成功登陆后的操作
				request.getRequestDispatcher("./sc.jsp").forward(request,
						response);

			} else {
				request.setAttribute("msg", "用户名或者密码错误");
				request.getRequestDispatcher("./index.jsp").forward(request,
						response);
			}

		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}

	/**
	 * md5加密处理
	 * @param value
	 * @return
	 */
	public String md5Value(String value) {
		try {
			MessageDigest digest = MessageDigest.getInstance("md5");
			byte result[] = digest.digest(value.getBytes());
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(result);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

}

3.有关自动完成登录过滤器的代码如下

package www.csdn.net.day56.filter;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

import www.csdn.net.day56.bean.Admin;
import www.csdn.net.day56.service.AdminService;
import www.csdn.net.day56.service.impl.AdminServiceImpl;

public class AutoLoginFilter implements Filter {

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

		// 造型对象
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;

		// 1.首先判断sesion中有没有admin
		Object object = request.getSession().getAttribute("admin");
		// 如果session中有用户
		if (object != null) {
			// 跳转到成功登录的界面
			request.getRequestDispatcher("./sc.jsp").forward(request, response);
			return;
		}
		/*---------------------------以下是当session中不存在admin信息时候的处理---------------------------------*/
		// 2.判断cookie中是否存在 autologin标识符 的cookie对象
		// 声明cookie
		Cookie autoCookie = null;
		// 获取所有的cookie
		Cookie cookies[] = request.getCookies();
		// 如果没有cookie信息,就继续执行login.do,跳转到login.jsp页面
		if (cookies != null) {
			// 如果有,就遍历cookie
			for (Cookie cookie : cookies) {
				// 判断cookie中是否有autologin标识符的cookie
				if ("autologin".equals(cookie.getName())) {
					autoCookie = cookie; // 如果有 就赋值给临时变量autoCookie
				}
			}

			// 3. 判断autoCookie是否等于null
			if (autoCookie == null) {
				// 如果等于null,则继续执行login.jsp页面
				chain.doFilter(request, response);
				return;
			}

			// 3.如果autoCookie不等于null,就判断cookie的值
			// 获取cookie值
			String value = autoCookie.getValue();
			// 拆分cookie的值
			String temp[] = value.split(":");
			System.out.println(temp.length);
			// 判断长度 是否等于自己拼接的长度
			if (temp.length != 3) {
				// 如果不等于3,则继续执行login.jsp页面
				chain.doFilter(request, response);
				return;
			}

			// 获取cookie拆分的各个值
			String name = temp[0]; // 用户名
			String time = temp[1];// 获取有效时间
			String service_md5Value = temp[2];// 获取md5的加密后的字符
			// 4.判断cookie是否失效
			if (Long.valueOf(time) <= System.currentTimeMillis()) {
				// 如果失效,则继续执行login.jsp页面
				chain.doFilter(request, response);
				return;
			}

			// 5.如果cookie没有失效,根据用户名,去查询用户信息
			AdminService adminService = new AdminServiceImpl();
			// 查询用户信息
			Admin entity = adminService.checkLogin(name);
			System.out.println(entity+"0000");
			// 判断用户是否为null
			if (entity == null) {
				// 如果没有查询的用户,则继续执行login.jsp页面
				chain.doFilter(request, response);
				return;
			}

			// 按照服务器拼接的字符的方式,拼接md5加密的字符串
			String md5Temp = entity.getName() + ":" + entity.getPass() + ":"
					+ time;
			// 判断md5加密后和服务器端加密的字符是否相等
			if (!(md5Value(md5Temp).equals(service_md5Value))) {
				// 在不相等的情况下,则继续执行login.jsp页面
				chain.doFilter(request, response);
				return;
			}

			// 如果满足了cookie取值判断的所有结果,则跳转到成功登录的界面.
			request.getSession().setAttribute("admin", entity);
			request.getRequestDispatcher("./sc.jsp").forward(request, response);
		} else {
			// 在没有cookie信息的时候,则继续login.jsp页面
			chain.doFilter(request, response);
			return;
		}
	}

	// md5加密字符串
	public String md5Value(String value) {
		try {
			MessageDigest digest = MessageDigest.getInstance("md5");
			byte result[] = digest.digest(value.getBytes());
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(result);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return "";
	}

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

	}

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

	}
}

4.在web.xml文件中配置过滤器

  <filter>
    <filter-name>AutoLoginFilter</filter-name>
    <filter-class>www.csdn.net.day56.filter.AutoLoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>AutoLoginFilter</filter-name>
    <url-pattern>/login.jsp</url-pattern>
  </filter-mapping>

5.以上功能模块中涉及到的类或者接口如下:

    1.Admin.java类

    

package www.csdn.net.day56.bean;

import java.io.Serializable;

public class Admin  implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private String pass;
	public Admin() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Admin(Integer id, String name, String pass) {
		super();
		this.id = id;
		this.name = name;
		this.pass = pass;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPass() {
		return pass;
	}
	public void setPass(String pass) {
		this.pass = pass;
	}
	
	
	
}

2.BaseDao接口

 

package www.csdn.net.day56.dao;

public interface BaseDao<T, PK> {
	
}

3.AdminDao接口

package www.csdn.net.day56.dao;

import www.csdn.net.day56.bean.Admin;

public interface AdminDao  extends BaseDao<Admin,Integer>{

	
	/**
	 * 用户登录验证的操作
	 * @param name
	 * @param pass
	 * @return
	 */
	public Admin checkLogin(String name,String pass);
	
	/**
	 * 
	 * @param name
	 * @return
	 */
	public Admin checkLogin(String name);
}

4.AdminDao接口的实现类

package www.csdn.net.day56.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import util.DBConn;
import www.csdn.net.day56.bean.Admin;
import www.csdn.net.day56.dao.AdminDao;

public class AdminDaoImpl implements AdminDao {

	private Connection conn;
	private PreparedStatement pstmt;
	private ResultSet rs;

	@Override
	public Admin checkLogin(String name, String pass) {
		Admin entity = null;

		conn = DBConn.getConn();

		String sql = "select * from admin where name=? and pass=? ";

		try {
			pstmt = conn.prepareStatement(sql);

			int index = 1;
			pstmt.setString(index++, name);
			pstmt.setString(index++, pass);

			rs = pstmt.executeQuery();

			if (rs.next()) {
				entity = new Admin();
				entity.setId(rs.getInt("id"));
				entity.setName(rs.getString("name"));
				entity.setPass(rs.getString("pass"));
			}

		} catch (Exception e) {

		} finally {
			DBConn.release(rs, pstmt);
		}
		return entity;
	}

	@Override
	public Admin checkLogin(String name) {
		Admin entity = null;

		conn = DBConn.getConn();

		String sql = "select * from admin where name=? ";

		try {
			pstmt = conn.prepareStatement(sql);

			int index = 1;
			pstmt.setString(index++, name);
			rs = pstmt.executeQuery();

			if (rs.next()) {
				entity = new Admin();
				entity.setId(rs.getInt("id"));
				entity.setName(rs.getString("name"));
				entity.setPass(rs.getString("pass"));
			}

		} catch (Exception e) {

		} finally {
			DBConn.release(rs, pstmt);
		}
		return entity;
	}

}

5.BaseService接口

package www.csdn.net.day56.service;

public interface BaseService<T, PK> {

}

6.AdminService接口

package www.csdn.net.day56.service;

import www.csdn.net.day56.bean.Admin;

public interface AdminService extends BaseService<Admin, Integer> {

    /**
     * 用户登录验证的操作
     * @param name
     * @param pass
     * @return
     */
    public Admin checkLogin(String name,String pass);
    
    
    /**
     *
     * @param name
     * @return
     */
    public Admin checkLogin(String name);
}

7.AdminService接口的实现类

package www.csdn.net.day56.service.impl;

import www.csdn.net.day56.bean.Admin;
import www.csdn.net.day56.dao.AdminDao;
import www.csdn.net.day56.dao.impl.AdminDaoImpl;
import www.csdn.net.day56.service.AdminService;

public class AdminServiceImpl implements AdminService {

	private AdminDao adminDao = new AdminDaoImpl();
	
	
	@Override
	public Admin checkLogin(String name, String pass) {
		Admin entity  = adminDao.checkLogin(name, pass);
		return entity;
	}


	@Override
	public Admin checkLogin(String name) {
	
		return adminDao.checkLogin(name);
	}

}

8.工具类

 

package util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.commons.io.FileUtils;

public class DBConn {

	private static Connection conn;

	private DBConn() {

	}

	public static Connection getConn() {
		try {
			if (conn == null) {
				// 创建集合对象
				Properties properties = new Properties();
				// 装载
				properties.load(DBConn.class.getClassLoader()
						.getResourceAsStream("db.properties"));
				// 加载驱动程序
				Class.forName(properties.getProperty("driverClassName"));
				// 获取连接对象
				conn = DriverManager.getConnection(
						properties.getProperty("url"),
						properties.getProperty("user"),
						properties.getProperty("pass"));

				// 修改事务 为手动提交方式
				conn.setAutoCommit(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return conn;
	}

	public static void update(String sql, Object params[],
			PreparedStatement pstmt) throws Exception {
		try {
			pstmt = getConn().prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}
			pstmt.executeUpdate();
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			e.printStackTrace();
		} finally {
			release(null, pstmt);
		}
	}

	public static void release(ResultSet rs, PreparedStatement pstmt) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (pstmt != null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}

下面进行效果演示说明

    1.打开登录界面,输入正确的用户名和密码,勾选上自动登录操作.

    

  2.点击登录按钮,登录成功后,跳转到sc.jsp页面

3.重新进入登录界面

发现,完成了自动登录的功能模块.

如果你关闭tomcat,重新启动,你会发现,只要在cookie的有效时间中,并且用户名和密码没有做修改的情况下,只要你进入登录界面.用户就会自动登录,并跳转到sc.jsp页面.效果同上图.

抱歉!评论已关闭.