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

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

2014年06月28日 ⁄ 综合 ⁄ 共 19483字 ⁄ 字号 评论关闭

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

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

      

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

     

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

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

       

 

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

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

1.编写登录界面

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2.   
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5.   <head>  
  6.      
  7.     <title>My JSP 'index.jsp' starting page</title>  
  8.     <meta http-equiv="pragma" content="no-cache">  
  9.     <meta http-equiv="cache-control" content="no-cache">  
  10.     <meta http-equiv="expires" content="0">      
  11.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  12.     <meta http-equiv="description" content="This is my page">  
  13.     <!-- 
  14.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  15.     -->  
  16.       
  17.   </head>  
  18.     
  19.   <body>  
  20.      ${requestScope.msg}<br/>  
  21.       <form action="${pageContext.request.contextPath}/AdminOper.do" method="post">  
  22.         <table>  
  23.            <tr>  
  24.              <td>用户名:</td>  
  25.              <td><input type="text" name="name"/></td>  
  26.            </tr>  
  27.            <tr>  
  28.              <td>密码:</td>  
  29.              <td><input type="password" name="pass"/></td>  
  30.            </tr>  
  31.            <tr>  
  32.              <td colspan="2">  
  33.                <input type="radio" name="day" checked="checked" value="7">一周  
  34.                <input type="radio" name="day" value="30">一月  
  35.                <input type="radio" name="day" value="90">三个月  
  36.              </td>  
  37.            </tr>  
  38.            <tr>  
  39.              <td><input type="checkbox" name="mark" value="mark"/></td>  
  40.              <td>下次自动登陆</td>  
  41.            </tr>  
  42.            <tr>  
  43.              <td> <input type="submit" value="登陆"/></td>  
  44.              <td><input type="reset"  value="重置"/></td>  
  45.            </tr>  
  46.         </table>  
  47.          <input type="hidden" name="oper" value="login"/>  
  48.       </form>  
  49.   </body>  
  50. </html>  

效果如下:

  

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

  1. package www.csdn.net.day56.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.security.MessageDigest;  
  5. import java.security.NoSuchAlgorithmException;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.Cookie;  
  9. import javax.servlet.http.HttpServlet;  
  10. import javax.servlet.http.HttpServletRequest;  
  11. import javax.servlet.http.HttpServletResponse;  
  12.   
  13. import sun.misc.BASE64Encoder;  
  14.   
  15. import com.sun.mail.util.BASE64EncoderStream;  
  16.   
  17. import www.csdn.net.day56.bean.Admin;  
  18. import www.csdn.net.day56.dao.AdminDao;  
  19. import www.csdn.net.day56.dao.impl.AdminDaoImpl;  
  20. import www.csdn.net.day56.service.AdminService;  
  21. import www.csdn.net.day56.service.impl.AdminServiceImpl;  
  22.   
  23. public class AdminServlet extends HttpServlet {  
  24.   
  25.     private AdminService adminService = new AdminServiceImpl();  
  26.   
  27.     private long expires = 24 * 60 * 60// 1天  
  28.   
  29.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  30.             throws ServletException, IOException {  
  31.   
  32.         String method = request.getMethod();  
  33.         System.out.println("请求的方法::::" + method);  
  34.         // 获取请求参数中 操作的标识符  
  35.         String oper = request.getParameter("oper");  
  36.   
  37.         if ("login".equals(oper)) {  
  38.             // 处理登陆  
  39.             // 获取用户名和密码  
  40.             String name = request.getParameter("name");  
  41.             String pass = request.getParameter("pass");  
  42.             //获取标记 是否自动登录标识符  
  43.             String mark = request.getParameter("mark");  
  44.   
  45.             // 验证用户名和密码是否正确  
  46.             Admin entity = adminService.checkLogin(name, pass);  
  47.   
  48.             if (entity != null) {  
  49.                 // 判断是自动登录处理  
  50.                 if ("mark".equals(mark)) {  
  51.                     // 获取默认记住的天数  
  52.                     String day = request.getParameter("day");  
  53.                     // 转换成有效的时间  
  54.                     expires = Integer.valueOf(day) * expires;  
  55.                     // 声明cookie  
  56.                     Cookie autoCookie = null;  
  57.                     // 获取所有cookie  
  58.                     Cookie cookies[] = request.getCookies();  
  59.                     // 遍历cookie  
  60.                     for (Cookie cookie : cookies) {  
  61.                         // 判断是否存在自动登陆记录  
  62.                         if ("autologin".equals(cookie.getName())) {  
  63.                             autoCookie = cookie; // 赋值  
  64.   
  65.                             // 当cookie存在的时候,我需要重新设置值  
  66.                             long time = (System.currentTimeMillis() + expires * 1000);  
  67.                             //cookie拼接的value值,(可以根据自己的想法设计)  
  68.                             String newValue = name + ":" + time + ":"  
  69.                                     + md5Value(name + ":" + pass + ":" + time);  
  70.                             //设置值  
  71.                             autoCookie .setValue(newValue);  
  72.                         } else {  
  73.                             // 不存在创建  
  74.                             // name+":"+time+":"+md5(name:pass:time)  
  75.                             long time = System.currentTimeMillis() + expires  
  76.                                     * 1000;  
  77.                             //cookie拼接的value值,(可以根据自己的想法设计)  
  78.                             String cookieValue = name + ":" + time + ":"  
  79.                                     + md5Value(name + ":" + pass + ":" + time);  
  80.                             //创建cookie  
  81.                             autoCookie = new Cookie("autologin", cookieValue);  
  82.                         }  
  83.                     }  
  84.   
  85.                     autoCookie.setMaxAge((int) expires);  
  86.                     autoCookie.setPath("/day56");  
  87.                     // 添加cookie  
  88.                     response.addCookie(autoCookie);  
  89.   
  90.                 }  
  91.                 // admin存入到session  
  92.                 request.getSession().setAttribute("admin", entity);  
  93.                 // 成功登陆后的操作  
  94.                 request.getRequestDispatcher("./sc.jsp").forward(request,  
  95.                         response);  
  96.   
  97.             } else {  
  98.                 request.setAttribute("msg""用户名或者密码错误");  
  99.                 request.getRequestDispatcher("./index.jsp").forward(request,  
  100.                         response);  
  101.             }  
  102.   
  103.         }  
  104.   
  105.     }  
  106.   
  107.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  108.             throws ServletException, IOException {  
  109.         this.doGet(request, response);  
  110.     }  
  111.   
  112.     /** 
  113.      * md5加密处理 
  114.      * @param value 
  115.      * @return 
  116.      */  
  117.     public String md5Value(String value) {  
  118.         try {  
  119.             MessageDigest digest = MessageDigest.getInstance("md5");  
  120.             byte result[] = digest.digest(value.getBytes());  
  121.             BASE64Encoder encoder = new BASE64Encoder();  
  122.             return encoder.encode(result);  
  123.         } catch (NoSuchAlgorithmException e) {  
  124.             // TODO Auto-generated catch block  
  125.             e.printStackTrace();  
  126.         }  
  127.         return "";  
  128.     }  
  129.   
  130. }  

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

  1. package www.csdn.net.day56.filter;  
  2.   
  3. import java.io.IOException;  
  4. import java.security.MessageDigest;  
  5. import java.security.NoSuchAlgorithmException;  
  6.   
  7. import javax.servlet.Filter;  
  8. import javax.servlet.FilterChain;  
  9. import javax.servlet.FilterConfig;  
  10. import javax.servlet.ServletException;  
  11. import javax.servlet.ServletRequest;  
  12. import javax.servlet.ServletResponse;  
  13. import javax.servlet.http.Cookie;  
  14. import javax.servlet.http.HttpServletRequest;  
  15. import javax.servlet.http.HttpServletResponse;  
  16.   
  17. import sun.misc.BASE64Encoder;  
  18.   
  19. import www.csdn.net.day56.bean.Admin;  
  20. import www.csdn.net.day56.service.AdminService;  
  21. import www.csdn.net.day56.service.impl.AdminServiceImpl;  
  22.   
  23. public class AutoLoginFilter implements Filter {  
  24.   
  25.     @Override  
  26.     public void doFilter(ServletRequest req, ServletResponse res,  
  27.             FilterChain chain) throws IOException, ServletException {  
  28.   
  29.         // 造型对象  
  30.         HttpServletRequest request = (HttpServletRequest) req;  
  31.         HttpServletResponse response = (HttpServletResponse) res;  
  32.   
  33.         // 1.首先判断sesion中有没有admin  
  34.         Object object = request.getSession().getAttribute("admin");  
  35.         // 如果session中有用户  
  36.         if (object != null) {  
  37.             // 跳转到成功登录的界面  
  38.             request.getRequestDispatcher("./sc.jsp").forward(request, response);  
  39.             return;  
  40.         }  
  41.         /*---------------------------以下是当session中不存在admin信息时候的处理---------------------------------*/  
  42.         // 2.判断cookie中是否存在 autologin标识符 的cookie对象  
  43.         // 声明cookie  
  44.         Cookie autoCookie = null;  
  45.         // 获取所有的cookie  
  46.         Cookie cookies[] = request.getCookies();  
  47.         // 如果没有cookie信息,就继续执行login.do,跳转到login.jsp页面  
  48.         if (cookies != null) {  
  49.             // 如果有,就遍历cookie  
  50.             for (Cookie cookie : cookies) {  
  51.                 // 判断cookie中是否有autologin标识符的cookie  
  52.                 if ("autologin".equals(cookie.getName())) {  
  53.                     autoCookie = cookie; // 如果有 就赋值给临时变量autoCookie  
  54.                 }  
  55.             }  
  56.   
  57.             // 3. 判断autoCookie是否等于null  
  58.             if (autoCookie == null) {  
  59.                 // 如果等于null,则继续执行login.jsp页面  
  60.                 chain.doFilter(request, response);  
  61.                 return;  
  62.             }  
  63.   
  64.             // 3.如果autoCookie不等于null,就判断cookie的值  
  65.             // 获取cookie值  
  66.             String value = autoCookie.getValue();  
  67.             // 拆分cookie的值  
  68.             String temp[] = value.split(":");  
  69.             System.out.println(temp.length);  
  70.             // 判断长度 是否等于自己拼接的长度  
  71.             if (temp.length != 3) {  
  72.                 // 如果不等于3,则继续执行login.jsp页面  
  73.                 chain.doFilter(request, response);  
  74.                 return;  
  75.             }  
  76.   
  77.             // 获取cookie拆分的各个值  
  78.             String name = temp[0]; // 用户名  
  79.             String time = temp[1];// 获取有效时间  
  80.             String service_md5Value = temp[2];// 获取md5的加密后的字符  
  81.             // 4.判断cookie是否失效  
  82.             if (Long.valueOf(time) <= System.currentTimeMillis()) {  
  83.                 // 如果失效,则继续执行login.jsp页面  
  84.                 chain.doFilter(request, response);  
  85.                 return;  
  86.             }  
  87.   
  88.             // 5.如果cookie没有失效,根据用户名,去查询用户信息  
  89.             AdminService adminService = new AdminServiceImpl();  
  90.             // 查询用户信息  
  91.             Admin entity = adminService.checkLogin(name);  
  92.             System.out.println(entity+"0000");  
  93.             // 判断用户是否为null  
  94.             if (entity == null) {  
  95.                 // 如果没有查询的用户,则继续执行login.jsp页面  
  96.                 chain.doFilter(request, response);  
  97.                 return;  
  98.             }  
  99.   
  100.             // 按照服务器拼接的字符的方式,拼接md5加密的字符串  
  101.             String md5Temp = entity.getName() + ":" + entity.getPass() + ":"  
  102.                     + time;  
  103.             // 判断md5加密后和服务器端加密的字符是否相等  
  104.             if (!(md5Value(md5Temp).equals(service_md5Value))) {  
  105.                 // 在不相等的情况下,则继续执行login.jsp页面  
  106.                 chain.doFilter(request, response);  
  107.                 return;  
  108.             }  
  109.   
  110.             // 如果满足了cookie取值判断的所有结果,则跳转到成功登录的界面.  
  111.             request.getSession().setAttribute("admin", entity);  
  112.             request.getRequestDispatcher("./sc.jsp").forward(request, response);  
  113.         } else {  
  114.             // 在没有cookie信息的时候,则继续login.jsp页面  
  115.             chain.doFilter(request, response);  
  116.             return;  
  117.         }  
  118.     }  
  119.   
  120.     // md5加密字符串  
  121.     public String md5Value(String value) {  
  122.         try {  
  123.             MessageDigest digest = MessageDigest.getInstance("md5");  
  124.             byte result[] = digest.digest(value.getBytes());  
  125.             BASE64Encoder encoder = new BASE64Encoder();  
  126.             return encoder.encode(result);  
  127.         } catch (NoSuchAlgorithmException e) {  
  128.             e.printStackTrace();  
  129.         }  
  130.         return "";  
  131.     }  
  132.   
  133.     @Override  
  134.     public void init(FilterConfig arg0) throws ServletException {  
  135.         // TODO Auto-generated method stub  
  136.   
  137.     }  
  138.   
  139.     @Override  
  140.     public void destroy() {  
  141.         // TODO Auto-generated method stub  
  142.   
  143.     }  
  144. }  

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

  1. <filter>  
  2.   <filter-name>AutoLoginFilter</filter-name>  
  3.   <filter-class>www.csdn.net.day56.filter.AutoLoginFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6.   <filter-name>AutoLoginFilter</filter-name>  
  7.   <url-pattern>/login.jsp</url-pattern>  
  8. </filter-mapping>  

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

    1.Admin.java类

    

  1. package www.csdn.net.day56.bean;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Admin  implements Serializable{  
  6.   
  7.     /** 
  8.      *  
  9.      */  
  10.     private static final long serialVersionUID = 1L;  
  11.     private Integer id;  
  12.     private String name;  
  13.     private String pass;  
  14.     public Admin() {  
  15.         super();  
  16.         // TODO Auto-generated constructor stub  
  17.     }  
  18.     public Admin(Integer id, String name, String pass) {  
  19.         super();  
  20.         this.id = id;  
  21.         this.name = name;  
  22.         this.pass = pass;  
  23.     }  
  24.     public Integer getId() {  
  25.         return id;  
  26.     }  
  27.     public void setId(Integer id) {  
  28.         this.id = id;  
  29.     }  
  30.     public String getName() {  
  31.         return name;  
  32.     }  
  33.     public void setName(String name) {  
  34.         this.name = name;  
  35.     }  
  36.     public String getPass() {  
  37.         return pass;  
  38.     }  
  39.     public void setPass(String pass) {  
  40.         this.pass = pass;  
  41.     }  
  42.       
  43.       
  44.       
  45. }  

2.BaseDao接口

 

  1. package www.csdn.net.day56.dao;  
  2.   
  3. public interface BaseDao<T, PK> {  
  4.       
  5. }  

3.AdminDao接口

  1. package www.csdn.net.day56.dao;  
  2.   
  3. import www.csdn.net.day56.bean.Admin;  
  4.   
  5. public interface AdminDao  extends BaseDao<Admin,Integer>{  
  6.   
  7.       
  8.     /** 
  9.      * 用户登录验证的操作 
  10.      * @param name 
  11.      * @param pass 
  12.      * @return 
  13.      */  
  14.     public Admin checkLogin(String name,String pass);  
  15.       
  16.     /** 
  17.      *  
  18.      * @param name 
  19.      * @return 
  20.      */  
  21.     public Admin checkLogin(String name);  
  22. }  

4.AdminDao接口的实现类

  1. package www.csdn.net.day56.dao.impl;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.ResultSet;  
  6.   
  7. import util.DBConn;  
  8. import www.csdn.net.day56.bean.Admin;  
  9. import www.csdn.net.day56.dao.AdminDao;  
  10.   
  11. public class AdminDaoImpl implements AdminDao {  
  12.   
  13.     private Connection conn;  
  14.     private PreparedStatement pstmt;  
  15.     private ResultSet rs;  
  16.   
  17.     @Override  
  18.     public Admin checkLogin(String name, String pass) {  
  19.         Admin entity = null;  
  20.   
  21.         conn = DBConn.getConn();  
  22.   
  23.         String sql = "select * from admin where name=? and pass=? ";  
  24.   
  25.         try {  
  26.             pstmt = conn.prepareStatement(sql);  
  27.   
  28.             int index = 1;  
  29.             pstmt.setString(index++, name);  
  30.             pstmt.setString(index++, pass);  
  31.   
  32.             rs = pstmt.executeQuery();  
  33.   
  34.             if (rs.next()) {  
  35.                 entity = new Admin();  
  36.                 entity.setId(rs.getInt("id"));  
  37.                 entity.setName(rs.getString("name"));  
  38.                 entity.setPass(rs.getString("pass"));  
  39.             }  
  40.   
  41.         } catch (Exception e) {  
  42.   
  43.         } finally {  
  44.             DBConn.release(rs, pstmt);  
  45.         }  
  46.         return entity;  
  47.     }  
  48.   
  49.     @Override  
  50.     public Admin checkLogin(String name) {  
  51.         Admin entity = null;  
  52.   
  53.         conn = DBConn.getConn();  
  54.   
  55.         String sql = "select * from admin where name=? ";  
  56.   
  57.         try {  
  58.             pstmt = conn.prepareStatement(sql);  
  59.   
  60.             int index = 1;  
  61.             pstmt.setString(index++, name);  
  62.             rs = pstmt.executeQuery();  
  63.   
  64.             if (rs.next()) {  
  65.                 entity = new Admin();  
  66.                 entity.setId(rs.getInt("id"));  
  67.                 entity.setName(rs.getString("name"));  
  68.                 entity.setPass(rs.getString("pass"));  
  69.             }  
  70.   
  71.         } catch (Exception e) {  
  72.   
  73.         } finally {  
  74.             DBConn.release(rs, pstmt);  
  75.         }  
  76.         return entity;  
  77.     }  
  78.   
  79. }  

5.BaseService接口

  1. package www.csdn.net.day56.service;  
  2.   
  3. public interface BaseService<T, PK> {  
  4.   
  5. }  

6.AdminService接口

  1. package www.csdn.net.day56.service;  
  2.   
  3. import www.csdn.net.day56.bean.Admin;  
  4.   
  5. public interface AdminService extends BaseService<Admin, Integer> {  
  6.   
  7.     /** 
  8.      * 用户登录验证的操作 
  9.      * @param name 
  10.      * @param pass 
  11.      * @return 
  12.      */  
  13.     public Admin checkLogin(String name,String pass);  
  14.       
  15.       
  16.     /** 
  17.      * 
  18.      * @param name 
  19.      * @return 
  20.      */  
  21.     public Admin checkLogin(String name);  
  22. }  

7.AdminService接口的实现类

  1. package www.csdn.net.day56.service.impl;  
  2.   
  3. import www.csdn.net.day56.bean.Admin;  
  4. import www.csdn.net.day56.dao.AdminDao;  
  5. import www.csdn.net.day56.dao.impl.AdminDaoImpl;  
  6. import www.csdn.net.day56.service.AdminService;  
  7.   
  8. public class AdminServiceImpl implements AdminService {  
  9.   
  10.     private AdminDao adminDao = new AdminDaoImpl();  
  11.       
  12.       
  13.     @Override  
  14.     public Admin checkLogin(String name, String pass) {  
  15.         Admin entity  = adminDao.checkLogin(name, pass);  
  16.         return entity;  
  17.     }  
  18.   
  19.   
  20.     @Override  
  21.     public Admin checkLogin(String name) {  
  22.       
  23.         return adminDao.checkLogin(name);  
  24.     }  
  25.   
  26. }  

8.工具类

 

  1. package util;  
  2.   
  3. import java.io.InputStream;  
  4. import java.sql.Connection;  
  5. import java.sql.DriverManager;  
  6. import java.sql.PreparedStatement;  
  7. import java.sql.ResultSet;  
  8. import java.sql.SQLException;  
  9. import java.util.Properties;  
  10.   
  11. import org.apache.commons.io.FileUtils;  
  12.   
  13. public class DBConn {  
  14.   
  15.     private static Connection conn;  
  16.   
  17.     private DBConn() {  
  18.   
  19.     }  
  20.   
  21.     public static Connection getConn() {  
  22.         try {  
  23.             if (conn == null) {  
  24.                 // 创建集合对象  
  25.                 Properties properties = new Properties();  
  26.                 // 装载  
  27.                 properties.load(DBConn.class.getClassLoader()  
  28.                         .getResourceAsStream("db.properties"));  
  29.                 // 加载驱动程序  
  30.                 Class.forName(properties.getProperty("driverClassName"));  
  31.                 // 获取连接对象  
  32.                 conn = DriverManager.getConnection(  
  33.                         properties.getProperty("url"),  
  34.                         properties.getProperty("user"),  
  35.                         properties.getProperty("pass"));  
  36.   
  37.                 // 修改事务 为手动提交方式  
  38.                 conn.setAutoCommit(false);  
  39.             }  
  40.         } catch (Exception e) {  
  41.             e.printStackTrace();  
  42.         }  
  43.   
  44.         return conn;  
  45.     }  
  46.   
  47.     public static void update(String sql, Object params[],  
  48.             PreparedStatement pstmt) throws Exception {  
  49.         try {  
  50.             pstmt = getConn().prepareStatement(sql);  
  51.             for (int i = 0; i < params.length; i++) {  
  52.                 pstmt.setObject(i + 1, params[i]);  
  53.             }  
  54.             pstmt.executeUpdate();  
  55.             conn.commit();  
  56.         } catch (Exception e) {  
  57.             conn.rollback();  
  58.             e.printStackTrace();  
  59.         } finally {  
  60.             release(null, pstmt);  
  61.         }  
  62.     }  
  63.   
  64.     public static void release(ResultSet rs, PreparedStatement pstmt) {  
  65.         if (rs != null) {  
  66.             try {  
  67.                 rs.close();  
  68.             } catch (SQLException e) {  
  69.                 // TODO Auto-generated catch block  
  70.                 e.printStackTrace();  
  71.             }  
  72.         }  
  73.         if (pstmt != null) {  
  74.             try {  
  75.                 pstmt.close();  
  76.             } catch (SQLException e) {  
  77.                 // TODO Auto-generated catch block  
  78.                 e.printStackTrace();  
  79.             }  
  80.         }  
  81.   
  82.     }  
  83. }  

下面进行效果演示说明

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

    

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

3.重新进入登录界面

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

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

【上篇】
【下篇】

抱歉!评论已关闭.