0


Session | 基于Session改造oa项目的登录功能

一:总结域对象

(1)request(对应的类名:HttpServletRequest)

  • 请求域(请求级别的)

(2)session(对应的类名:HttpSession)

  • 会话域(用户级别的)

(3)application(对应的类名:ServletContext)

  • 应用域(项目级别的,所有用户共享的)

(4)三个域对象的大小关系:request < session < application

(5)三个域对象都有以下三个公共的方法:

  • setAttribute(向域当中绑定数据)
  • getAttribute(从域当中获取数据)
  • removeAttribute(删除域当中的数据)

(6)使用原则:尽量使用小的域!

二:基于Session改造oa项目的登录功能

(1)前面oa项目增加用户登录的功能 这篇博客已经论述了,我们增加的登录页面实际上没有真正起到作用;所以学了session以后要进行优化!

(2)思路:登录成功之后,可以将用户的登录信息存储到session当中。

    也就是说session中如果有用户的信息就代表用户登录成功了!

    session中没有用户信息,表示用户没有登录过。则跳转到登录页面!

第一处修改:登录页面的类UserServlet

(1)原来的逻辑是登录成功,直接跳转到展示页面/dept/list;对应的类是DeptServlet;现在要在之前调用getSession()方法获取session对象,把用户名username放进去。

(2)这里不用加参数false,我们登录成功一定要获取session对象的,如果没有就新建一个;如果加了false就不会新建,没有会直接返回null。

        // 登录成功/失败
        if (success) {

            // 登录成功,是一定要获取session
            HttpSession session = request.getSession();
            // 把用户名放进session
            session.setAttribute("username",username);

            response.sendRedirect(request.getContextPath()+"/dept/list");
        }else{
            // 登录失败
            response.sendRedirect(request.getContextPath()+"/error.jsp");
        }

第二处修改:列表信息展示类****DeptServlet

(1)登录成功后,会把用户名放到session,这里要进行入口的验证;要加上false,只是获取当前session对象,获取不到就返回null;不需要新建session!

(2)如果获取不到session对象或者说获取不到session对象的username,表示没有登录过,需要跳转到登录页面进行登录;否则,表示登录过,就可以展示列表页面!

(3)达到的效果:直接跳过登录页面,直接访问/dept/list资源是行不通的;但是只要登录上,当前会话没结束(浏览器没关闭);打开新的窗口,直接访问/dept/list资源也是可以的;因为访问的一直是同一个session对象!

        // 入口的验证:获取session 加上false,表示不需要新建session
        // 只是获取当前session对象,获取不到就返回null
        HttpSession session = request.getSession(false);

        if (session != null && session.getAttribute("username") != null){
            // 获取servlet path
            String servletPath = request.getServletPath();
            if ("/dept/list".equals(servletPath)){
                doList(request,response);
            }else if("/dept/detail".equals(servletPath)){
                doDetail(request,response);
            }else if("/dept/delete".equals(servletPath)) {
                doDel(request, response);
            }else if("/dept/add".equals(servletPath)) {
                doAdd(request, response);
            }else if("/dept/modify".equals(servletPath)) {
                doModify(request, response);
            }
        }else{
            // 跳转到登录页面
            response.sendRedirect(request.getContextPath()+"/index.jsp");
        }

第三处:访问jsp的时候不生成session对象

注意:就算前面登录页面的类UserServlet没有获取创建session对象(当然username也就没放进去);后面在列表信息展示类DeptServlet中也可能会获取到session对象;因为首先调用了index.jsp;JSP的内置对象当中有session对象!

    根据Tomcat服务器提示,找到以下路径,CATALINA_BASE:   "C:\Users\86177\.IntelliJIdea2018.3\system\tomcat\Tomcat_9_0_68_JavaWeb" 找到index_jsp.java发现以下代码:
javax.servlet.http.HttpSession session = null;
// 这里获取到了session对象
session = pageContext.getSession();

实际上是可以禁用生成session对象的!

在index.jsp中增加以下page指令,表示访问jsp的时候不生成session对象

<%@page session="false" %>

第四处:增加一个欢迎语句

我们登录成功后,已经把用户名放入session对象当中,所以可以直接从内置对象session当中取出username;但是如果使用<%@page session="false" %>,session对象就不能用了!

在list.jsp增加以下代码:

<h3>欢迎<%=session.getAttribute("username")%>登录</h3>

达到以下的页面效果,比如登录的是root用户:

三:oa项目的安全退出系统

手动销毁session对象,调用的是session的invalidate()方法!

第一处修改:index.jsp增加以下代码

<a href="<%=request.getContextPath()%>/dept/exit">退出系统</a>

第二处修改:UserServlet类中新增/dept/exit的编写

这里和登录页面/dept/login写在一块,使用同一个UserServlet;主要思想就是使用模板方法设计模式的思想减少类的使用!

package com.bjpowernode.oa.web.action;

import com.bjpowernode.oa.utils.DBUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.oa.web.action
 * @Project:JavaWeb
 * @name:UserServlet
 * @Date:2022/11/28 19:59
 */
@WebServlet({"/dept/login","/dept/exit"})
public class UserServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取servlet path
        String servletPath = request.getServletPath();
        if("/dept/login".equals(servletPath)){
            doLogin(request,response);
        }else if("/dept/exit".equals(servletPath)){
            doExit(request,response);
        }

    }

    /**
     * 退出系统,手动销毁session对象
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    protected void doExit(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取当前session对象
        HttpSession session = request.getSession(false);
        // 销毁session对象
        if (session != null) {
            // 手动销毁
            session.invalidate();
            // 销毁以后,跳到登录页面
            response.sendRedirect(request.getContextPath()+"/index.jsp");
        }

    }

    /**
     * 登录,创建session对象
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    protected void doLogin(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 打一个布尔标记
        boolean success = false;
        // 获取前端提交的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 连接数据库进行验证
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 获取连接
            conn = DBUtil.getCoonetion();
            // 获取预编译的数据库操作对象
            String sql = "select * from t_user where username=? and password=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, username);
            ps.setString(2, password);
            // 执行sql
            rs = ps.executeQuery();
            // 如果里面有数据表示登录成功:1条或者0条
            if (rs.next()) {
                success = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(conn, ps, rs);
        }

        // 登录成功/失败
        if (success) {
            // 登录成功,是一定要获取session
            // 获取session对象(不需要加参数false,不能返回null)
            // 必须获取到session,没有就新创建一个session
            HttpSession session = request.getSession();
            // 把用户名放进session
            session.setAttribute("username",username);

            response.sendRedirect(request.getContextPath()+"/dept/list");
        }else{
            // 登录失败
            response.sendRedirect(request.getContextPath()+"/error.jsp");
        }
    }
}

这样就增加了一个安全退出系统的按钮

标签: servlet session

本文转载自: https://blog.csdn.net/m0_61933976/article/details/128103476
版权归原作者 @每天都要敲代码 所有, 如有侵权,请联系我们删除。

“Session | 基于Session改造oa项目的登录功能”的评论:

还没有评论