用于登陆的实现

存session

package utils;

import org.apache.log4j.Logger;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: MySessionContext
 * @Description: 存储 Session对象,用于用户的强制下线等待操作
 * @author: GGBOY
 * @date 2019/12/10 14:12
 * @Version: 1.0
 **/
public class MySessionContext {
    /**
     * userID--->userSession
     */
    private static Map<String, HttpSession> sessionMap = new HashMap<>();
    static Logger logger = Logger.getLogger(MySessionContext.class);

    /**
     * 增加 Session对象
     *
     * @param session 要添加的用户 Session对象
     * @author GGBOY
     * @date 2019/12/10
     */
    public static synchronized void addSession(HttpSession session) {
        if (session != null) {
            logger.warn("添加Session对象,userId为:" + session.getAttribute("userId"));
            sessionMap.put((String) session.getAttribute("userId"), session);
        }
    }

    /**
     * 账号在其它地方登录,挤掉线时,删除已登录的session,即非正常退出
     *
     * @param session 要删除的sesion
     * @author GGBOY
     * @date 2019/12/11
     */
    public static synchronized void delSession(HttpSession session) {
        if (session != null) {
            try{
                String userId = (String) session.getAttribute("userId");
                if(userId != null && !"".equals(userId)){
                    //移出session
                    HttpSession session2 = sessionMap.remove(userId);
                    if (session2 != null) {
                        logger.warn("要删除的SessionId:--------->" + session2.getId());
                        session2.setAttribute("msg", "你被踢下线!!!");

                    }
                }
            }catch (IllegalStateException e){
                // 如果发生了 Session already invalidated错误,不处理该错误
                e.printStackTrace();
            }
        }
    }

    /**
     * 正常退出时,删除 session
     *
     * @param session 要删除的session
     * @author GGBOY
     * @date 2019/12/11
     */
    public static synchronized void delSessionByNormalLogout(HttpSession session) {
        if (session != null) {
            //移出session
            sessionMap.remove(session.getAttribute("userId"));
        }
    }

    public static synchronized HttpSession getSession(String userId) {
        if (userId == null) {
            return null;
        }
        return (HttpSession) sessionMap.get(userId);
    }

    public static Map<String, HttpSession> getMySessionMap() {
        return sessionMap;
    }

    public static boolean isExitSession(String userId) {
        return sessionMap.containsKey(userId);
    }

}

校验是否被强制下线

package filter;

import domain.User;
import exception.LoginException;
import org.apache.log4j.Logger;
import service.UserService;
import utils.MySessionContext;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 用于自动登录以及控制用户登录(即只允许的多ip,单用户登录)的过滤器
 */
@WebFilter(filterName = "AutoLoginFilter", urlPatterns = {"*.do", "*.jsp"})
public class AutoLoginFilter implements Filter {
    static Logger logger = Logger.getLogger(AutoLoginFilter.class);

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        logger.warn("AutoLoginFilter............" + request.getRequestURI());

        // 获得自动登录的cookie
        Cookie[] cookies = request.getCookies();
        String autoLogin = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("autoLogin".equals(cookie.getName())) {
                    // 找到了指定的 cookie
                    autoLogin = cookie.getValue();
                    break;
                }
            }
        }
        // 判断session是否无效,如果无效则跳转到登录界面
        if (request.getSession().getAttribute("msg") != null) {
            request.getSession().removeAttribute("msg");
            System.out.println("session无效,重新登录");
            // 从客户端删除自动登录 cookie,防止用户通过回退键可以回去
            Cookie cookie = new Cookie("autoLogin", "msg");
            cookie.setPath(request.getContextPath());
            // 设置 cookie有效时间为0,表示通知浏览器立即删除这个cookie
            cookie.setMaxAge(0);
            response.addCookie(cookie);
            synchronized (this) {
                // 使当前登录用户的session失效,即被踢下线
                request.getSession().invalidate();
                request.getServletContext().setAttribute("msg", "你已被踢下线!!!");
                // 跳转到登录界面重新登录
                response.sendRedirect("loginOrRegister.do");
            }
        } else {
            // 如果没有登录,则自动登录
            if (autoLogin != null && (request.getSession().getAttribute("user") == null)) {
                logger.warn("自动登录!");
                // 做自动登录
                String[] parts = autoLogin.split("-");
                String username = parts[0];
                String password = parts[1];
                // 检查用户名和密码
                UserService service = new UserService();
                try {
                    User user = service.login(username, password);
                    synchronized (this) {
                        if (user != null) {
                            HttpSession session = MySessionContext.getSession(String.valueOf(user.getId()));
                            // 如果能获取到Session,就说明这个账号已经被登录或者这个Session还没失效,那么
                            // 下面要把这个Session失效,替换为新的Session
                            if (session != null) {
                                MySessionContext.delSession(session);
                            }
                            request.getSession().setAttribute("user", user);
                            request.getSession().setAttribute("userId", String.valueOf(user.getId()));
                            MySessionContext.addSession(request.getSession());
                        }
                    }
                } catch (LoginException e) {
                    e.printStackTrace();
                }
            }

            // 放行,让后续的过滤器再进行处理
            chain.doFilter(request, resp);
        }

    }

    @Override
    public void init(FilterConfig config) throws ServletException {

    }

}

校验是否需要重登

此类没有对用户过滤,即所有人可访问。可以在此加条件进行登陆过滤。

package filter;

import domain.User;
import exception.LoginException;
import org.apache.log4j.Logger;
import service.UserService;
import utils.MySessionContext;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 专门拦截登录请求的过滤器
 */
@WebFilter(filterName = "LoginFilter", urlPatterns = "/login.do")
public class LoginFilter implements Filter {
    static Logger logger = Logger.getLogger(LoginFilter.class);
    static String flag = "LoginFilter.............";

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        UserService service = new UserService();

        logger.warn(flag + username + " " + password);
        try {
            if (username != null && !"".equals(username)) {
                User user = service.login(username, password);
                if(user != null){
                    logger.warn(flag + " " + user.getId());
                    // 获得用户id对象的session对象
                    HttpSession session = MySessionContext.getSession(String.valueOf(user.getId()));
                    // 如果session对象不为空,则代表已经存在session对象,即已经有人登录过了
                    if (session != null) {
                        logger.warn(flag + "删除seesion");
                        // 将这个session对象删除
                        MySessionContext.delSession(session);
                    }
                }
            }
        } catch (LoginException e) {
            e.printStackTrace();
        }
        // 放行
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {

    }

}

登录接口

package web.servlet.client;

import domain.User;
import org.apache.log4j.Logger;
import service.UserService;
import utils.MySessionContext;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
    static Logger logger = Logger.getLogger(LoginServlet.class);

    /**
     * The doGet method of the servlet. <br>
     * <p>
     * This method is called when a form has its tag value method equals to get.
     *
     * @param request  the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException      if an error occurred
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");*/

        // 得到用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 实例化用户操作相关的逻辑层
        UserService service = new UserService();
        request.getServletContext().removeAttribute("msg");
        try {
            if(username != null && !"".equals(username)){
                // 进行登录验证,判断数据库是否存在这个用户
                User user = service.login(username, password);
                logger.warn("用户信息:" + user.toString());
                // 登录成功,将用户存储到 session中
                request.getSession().setAttribute("user", user);
                request.getSession().setAttribute("userId", String.valueOf(user.getId()));
                logger.warn("sessionId:------------>" + request.getSession().getId());
                // 将Session 添加到 map中
                MySessionContext.addSession(request.getSession());

                // 发送自动登录的 cookie
                String autoLogin = "3600";
                // 注意 cookie中的密码要加密
                Cookie cookie = new Cookie("autoLogin", username + "-" + password);
                cookie.setMaxAge(Integer.parseInt(autoLogin));
                cookie.setPath(request.getContextPath());
                response.addCookie(cookie);
                // 如果是管理员调到后台账户
                if ("admin".equals(user.getRole())) {
                    // TODO: 跳转到后台管理界面
                    response.sendRedirect("management/index.jsp");
                } else {
                    // TODO: 如果不是管理员,调到主页面
                    response.sendRedirect("main.do");
                }
            }
        } catch (
                Exception e) {
            e.printStackTrace();
            // 如果出现问题,登录失败,则将错误信息存储到request域中,并跳转回登录页面显示错误信息
            request.setAttribute("register_meesage", e.getMessage());
            request.getRequestDispatcher("loginAndRegister.jsp").forward(request, response);
            return;
        }

    }

    /**
     * The doPost method of the servlet. <br>
     * <p>
     * This method is called when a form has its tag value method equals to post.
     *
     * @param request  the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException      if an error occurred
     */
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);
    }

}

监听用户

package listener;

import domain.Visitor;
import utils.SessionUtil;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

@WebListener()
public class MyServletRequestListener implements ServletRequestListener {
    //用户集合
    private ArrayList<Visitor> visitors;


    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {

    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        //从servletContext中获的userList
        visitors = (ArrayList<Visitor>) sre.getServletContext().getAttribute("userList");
        //如果servletContext中没有userList对象  初始化userList
        if (visitors == null) {
            visitors = new ArrayList<Visitor>();
        }
        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();

        //sessionId
        String sessionId = request.getSession().getId();
        //如果当前sessionId不存在集合中  创建当前user对象
        if (SessionUtil.getUserBySessionId(visitors, sessionId) == null) {
            if(!"0:0:0:0:0:0:0:1".equals(getIpAddress(request))){
                Visitor visitor = new Visitor();
                visitor.setSessionId(sessionId);
                visitor.setIp(getIpAddress(request));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss");
                String time = sdf.format(new Date());
                visitor.setFirstTime(time);
                visitors.add(visitor);
            }

        }
        //将userList集合 保存到ServletContext
        sre.getServletContext().setAttribute("userList", visitors);
    }

    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip.contains(",")) {
            return ip.split(",")[0];
        } else {
            return ip;
        }
    }

}

判断用户是否已存在

package utils;

import domain.Visitor;

import java.util.ArrayList;

/**
 * @ClassName: SessionUtil
 * @Description: Session相关的工具类
 * @author: GGBOY
 * @date 2019/11/21 16:34
 * @Version: 1.0
 **/
public class SessionUtil {
    /**
     * 根据sessionId判断当前用户是否存在在集合中  如果存在 返回当前用户  否则返回null
     *
     * @param visitors  在线的观察者集合
     * @param sessionId session的id
     * @return domain.User
     * @author GGBOY
     * @date 2019/11/21
     */
    public static Visitor getUserBySessionId(ArrayList<Visitor> visitors, String sessionId) {
        for (Visitor visitor : visitors) {
            if (sessionId.equals(visitor.getSessionId())) {
                return visitor;
            }
        }
        return null;
    }
}

退出登录接口

package web.servlet.client;

import utils.MySessionContext;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = "/logout.do")
public class LogoutServlet extends HttpServlet {

    /**
     * The doGet method of the servlet. <br>
     * <p>
     * This method is called when a form has its tag value method equals to get.
     *
     * @param request  the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException      if an error occurred
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 移除 map中的这个session对象
        MySessionContext.delSessionByNormalLogout(request.getSession());
        // 将用户从session中移除
        request.getSession().removeAttribute("user");
        request.getSession().removeAttribute("userId");
        request.getSession().removeAttribute("msg");
        request.getServletContext().removeAttribute("msg");
        // 从客户端删除自动登录 cookie
        Cookie cookie = new Cookie("autoLogin", "msg");
        cookie.setPath(request.getContextPath());
        // 设置 cookie有效时间为0,表示通知浏览器立即删除这个cookie
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        // 重新跳转到 main.jsp界面进行显示
        response.sendRedirect("main.do");
    }

    /**
     * The doPost method of the servlet. <br>
     * <p>
     * This method is called when a form has its tag value method equals to post.
     *
     * @param request  the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException      if an error occurred
     */
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);
    }

}

防止退出后还能回退页面(可不加)

package filter;

import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 告诉浏览器不要使用本地缓存,防止用户退出后,通过回退键还能回去
 */
@WebFilter(filterName = "NoCacheFilter", urlPatterns = {"/main.do", "/main.jsp"})
public class NoCacheFilter implements Filter {
    static Logger logger = Logger.getLogger(NoCacheFilter.class);
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        logger.warn("-----------------NoCacheFilter------------------");

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        // HTTP 1.1.
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        // HTTP 1.0.
        response.setHeader("Pragma", "no-cache");
        // Proxies.
        response.setDateHeader("Expires", 0);
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值