您的位置:首页 > 运维架构 > 网站架构

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

2014-01-02 20:16 821 查看
网站自动登录操作分析,我以CSDN用户登录功能为例说明,

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

      


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

     


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

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

       


 

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

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

1.编写登录界面

[html]
view plaincopy





<%@ 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类.

[java]
view plaincopy





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.有关自动完成登录过滤器的代码如下

[java]
view plaincopy





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文件中配置过滤器

[html]
view plaincopy





<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类

    

[java]
view plaincopy





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接口
 

[java]
view plaincopy





package www.csdn.net.day56.dao;  
  
public interface BaseDao<T, PK> {  
      
}  

3.AdminDao接口

[java]
view plaincopy





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接口的实现类

[java]
view plaincopy





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接口

[java]
view plaincopy





package www.csdn.net.day56.service;  
  
public interface BaseService<T, PK> {  
  
}  

6.AdminService接口

[java]
view plaincopy





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接口的实现类

[java]
view plaincopy





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.工具类
 

[java]
view plaincopy





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页面.效果同上图.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: