1.掌握session后,如何解决oa项目中的登录问题,如何使登录发挥作用?441.1思路44
-登录成功后,用户的登录信息可以存储在session中。换句话说,如果session中有用户信息,则表示用户登录成功。session中没有用户信息,这意味着用户没有登录。跳转到登录页面。
-销毁session对象:45
session.invalidate();
2.使用cookie在10天内实现免登录功能。48-首先实现登录功能
-登录成功
-跳转到部门列表页面
-登录失败
-跳转到登录失败页面
-修改前端页面
-在登录页面上给出一个复选框,复选框后面给出一句话:十天内免登录。
-用户选择复选框:表示支持10天内免登录。
-用户不选择复选框:表示用户不想在十天内使用免登录功能。
-在Servlet中修改login方法
-如果用户登录成功,用户在登录时选择10天内免费登录功能,此时应在servletlogin方法中创建cookie,存储用户名和密码,并设置路径和有效期,并将cookie响应到浏览器。(浏览器将其自动存储在硬盘文件中10天)
-当用户再次访问该网站时,当访问该网站的主页时,有两个方向:
-或跳转到部门列表页面
-或跳转到登录页面
-以上有两个方向,显然需要编写java程序来控制。
3.代码com中的代码.bjpowernode.oa.bean.javabeanDeptpackage com.bjpowernode.oa.bean;import java.util.Objects;//这是一个普通的java类,可以包装分散的数据,代表部门对象public class Dept { private String deptno; private String dname; private String loc; public Dept() { } public String getDeptno() { return deptno; } public void setDeptno(String deptno) { this.deptno = deptno; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } @Override public String toString() { return "Dept{" + "deptno='" + deptno + '\'' + ", dname='" + dname + '\'' + ", loc='" + loc + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Dept dept = (Dept) o; return Objects.equals(deptno, dept.deptno) && Objects.equals(dname, dept.dname) && Objects.equals(loc, dept.loc); } @Override public int hashCode() { return Objects.hash(deptno, dname, loc); }}
com.bjpowernode.oa.utils工具类DBUtilpackage com.bjpowernode.oa.utils;import java.sql.*;import java.util.ResourceBundle;/** * JDBC工具类 27 */public class DBUtil { // 静态变量:在类加载过程中执行。 // 而且有序。自上而下的顺序。 // 绑定属性资源文件 private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc"); // key根据属性配置文件获得value private static String driver = bundle.getString("driver"); private static String url = bundle.getString("url"); private static String user = bundle.getString("user"); private static String password = bundle.getString("password"); static { // 注册驱动(注册驱动只需注册一次,放在静态代码块中。加载DBUTil类时执行。) try { // "com.mysql.jdbc.Driver" 是连接数据库的驱动,不能写死。因为Oracle数据库将来可能会连接起来。 // 在连接oracle数据库时,还需要修改java代码,这显然违反了OCP开关的原则。 // OCP开关原则:对扩展开放,对修改关闭。(什么是符合OCP?不需要修改java源代码进行功能扩展。) //Class.forName("com.mysql.jdbc.Driver"); Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 获取数据库连接对象 * @return conn 连接对象 * @throws SQLException */ public static Connection getConnection() throws SQLException { // 获取连接 Connection conn = DriverManager.getConnection(url, user, password); return conn; } /** * 释放资源 * @param conn 连接对象 * @param ps 数据库操作对象 * @param rs 结果集对象 */ public static void close(Connection conn, Statement ps, ResultSet rs){ if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (ps != null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }}
com中的代码.bjpowernode.oa.web.actionDeptServletpackage com.bjpowernode.oa.web.action;import com.bjpowernode.oa.bean.Dept;import com.bjpowernode.oa.utils.DBUtil;import jakarta.servlet.ServletException;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import jakarta.servlet.http.HttpSession;import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;///使用jsp改造单表的CRUD操作 38@WebServlet({"/dept/list","/dept/detail","/dept/delete","/dept/save","/dept/modify"})public class DeptServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取session(这个session不需要新建) 44 // 只获得当前的session,得不到,回到nulllllllllllllllllllll HttpSession session = request.getSession(false); ///这里解释为什么if有两个判断条件,因为毫无疑问,第一个保证session不是null。 // ,但是session.getattribute中的username不是空的,因为系统默认访问index文件 // ,因此,默认访问index文件也会产生session会话,因此需要添加第二个条件 if(session!=null && session.getAttribute("username")!=null){ 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/save".equals(servletPath)){ doSave(request, response); }else if("/dept/modify".equals(servletPath)){ doModify(request,response); } }else{ ///未登录自动跳转登录页面 //重定向 //三种写法 //response.sendRedirect("/oa/index.jsp");////普通老老实实的写法 //response.sendRedirect("/oa");///省略index.jsp,因为index文件会自动访问 response.sendRedirect(request.getContextPath()+"/index.jsp");//动态获取根写法,登录页面自动找到 } } //保存部门信息 40 private void doSave(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ //获取部门信息 // 注意乱码问题(Tomcat10不会出现这个问题) request.setCharacterEncoding("UTF-8"); String deptno = request.getParameter("deptno"); String dname = request.getParameter("dname"); String loc = request.getParameter("loc"); ///连接数据库执行insert语句 Connection conn = null; PreparedStatement ps = null; int count = 0; try { conn = DBUtil.getConnection(); String sql = "insert into dept(deptno, dname, loc) values(?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1,deptno); ps.setString(2,dname); ps.setString(3,loc); count = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn,ps,null); } if(count==1) { // 最好在这里使用重定向(浏览器会发送一个全新的请求。) // 浏览器在地址栏上发送请求,即get请求。 response.sendRedirect(request.getContextPath()+"/dept/list"); } } ////根据部门编号删除相应的部门 40 private void doDel(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ //获取部门编号 String deptno = request.getParameter("deptno"); //连接数据库,查询部门信息 Connection conn = null; PreparedStatement ps = null; int count = 0; try { conn = DBUtil.getConnection(); String sql = "delete from dept where deptno = ?"; ps = conn.prepareStatement(sql); ps.setString(1,deptno); count = ps.executeUpdate();///返回删除受影响的条数 } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn,ps,null); } if(count == 1){ ///成功删除 ////重定向列表页面 String contextPath = request.getContextPath();///获取应用程序的根路径 response.sendRedirect(contextPath+"/dept/list"); } } ///根据部门编号获取部门信息 39 private void doDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ ///创建部门对象 Dept dept = new Dept(); //获取部门编号 String dno = request.getParameter("dno"); ///根据部门编号获取部门信息 将部门信息封装成咖啡豆(即javabean) //连接数据库,查询部门信息 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DBUtil.getConnection(); String sql = "select dname,loc from dept where deptno=?"; ps = conn.prepareStatement(sql); ps.setString(1,dno); rs = ps.executeQuery(); ///这个结果只集中了一个数据,所以不需要while循环,只需要if if(rs.next()){ String dname = rs.getString("dname"); String loc = rs.getString("loc"); ///包装对象(创建豆子javabean) dept.setDeptno(dno); dept.setDname(dname); dept.setLoc(loc); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn,ps,rs); } ///这个豆子只有一个,所以不需要袋子(也就是不需要集合),只需要把袋子放在request域 request.setAttribute("dept",dept); //转发(不是重定向,因为要跳转到JSP进行数据显示) //request.getRequestDispatcher("/detail.jsp").forward(request,response); ///获得不同的标志(这个标志是我们的listt.自己添加jsp修改和细节,用于区分修改和细节的操作) //因为我们可以根据不同的标记转发到不同的页面 40 /* String f = request.getParameter("f"); if("m".equals(f)){ //转发到修改页面 request.getRequestDispatcher("/edit.jsp").forward(request,response); }else if("d".equals(f)){ //转发到详细页面 request.getRequestDispatcher("/detail.jsp").forward(request,response); }*/ //我们将简化上述代码 这是路径拼接 getParameter("f")得到标记 40 String forward = "/"+request.getParameter("f")+".jsp"; ///根据获得的拼接路径转发 request.getRequestDispatcher(forward).forward(request,response); } //连接数据库,查询所有部门信息,收集部门信息,然后跳转到JSP进行页面显示。38 private void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ //准备一个容器,专门用于存储部门 List depts = new ArrayList<>(); //连接数据库,查询所有部门信息 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //获取连接 conn = DBUtil.getConnection(); String sql = "select deptno,dname,loc from dept"; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); ///遍历结果集 while(rs.next()){ ///集中从结果中取出 String deptno = rs.getString("deptno"); String dname = rs.getString("dname"); String loc = rs.getString("loc"); ///将上述分散的数据封装成java对象 Dept dept = new Dept(); dept.setDeptno(deptno); dept.setDname(dname); dept.setLoc(loc); ////将部门对象放入list集中 depts.add(dept); } } catch (SQLException e) { e.printStackTrace(); } finally { ///关闭连接 DBUtil.close(conn,ps,rs); } ///将一个集合放入请求域 request.setAttribute("depList",depts); ///转发不要重定向 request.getRequestDispatcher("/list.jsp").forward(request,response); } ///修改操作 40 private void doModify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ////解决请求体中文乱码问题 request.setCharacterEncoding("UTF-8"); //获取表单数据 String deptno = request.getParameter("deptno"); String dname = request.getParameter("dname"); String loc = request.getParameter("loc"); ////连接数据库执行更新语句 Connection conn = null; ; PreparedStatement ps = null; int count = 0; try { conn = DBUtil.getConnection(); String sql = "update dept set dname = ?,loc = ?,loc = ? where deptno = ?"; ps = conn.prepareStatement(sql); ps.setString(1, dname); ps.setString(2, loc); ps.setString(3, deptno); count = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn, ps, null); } if (count == 1) { ///成功更新 //重定向 response.sendRedirect(request.getContextPath() + "/dept/list"); } }}
UserServletpackage com.bjpowernode.oa.web.action;import com.bjpowernode.oa.utils.DBUtil;import jakarta.servlet.ServletException;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.*;import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;///专门处理用户登录 41//Servlet负责业务处理//JSP负责页面显示@WebServlet({"/user/login","/user/exit"})public class UserServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String servletPath = request.getServletPath(); if("/user/login".equals(servletPath)){ doLogin(request,response);//调用登录 }else if("/user/exit".equals(servletPath)){ doExit(request,response);//调用退出 } } //退出 45 protected void doExit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ///获取session对象,销毁session HttpSession session = request.getSession(false); if (session !=null){ ////手动销毁sssion对象 session.invalidate(); //跳转登录页面 ///这是重定向 response.sendRedirect(request.getContextPath()); } } //登录 protected void doLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean success = false;///登录成功标志 ////验证用户名和密码是否正确 ///获取用户名和密码 // 您是这样提交前端的:username=admin&password=123 String username = request.getParameter("username"); String password = request.getParameter("password"); ////连接数据库验证用户名和密码 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DBUtil.getConnection(); String sql = "select * from t_user where username=? and password=? and password=?"; ///编译sql ps = conn.prepareStatement(sql); //给?赋值 ps.setString(1,username); ps.setString(2,password); //执行sql rs = ps.executeQuery(); ///这个结果只集中了一个数据 if (rs.next()) { ///成功登录 success = true; } } catch (SQLException e) { e.printStackTrace(); }finally { DBUtil.close(conn,ps,rs); } if(success){ // 获得session对象(这里的要求是:必须获得session 44 // ,没有session也要新建session对象。) HttpSession session = request.getSession();//session对象一定不能空nulll session.setAttribute("username",username);///存储用户名 ///成功登录,用户选择在10天内免费登录 String f = request.getParameter("f"); if("1".equals(f)){ ///创建cookie对象存储登录名称 Cookie cookie1 = new Cookie("username",username); ///创建cookie对象存储密码 Cookie cookie2 = new Cookie("password", password); ///设置cookie的有效时间为十天 cookie1.setMaxAge(60*60*24*10); cookie2.setMaxAge(60*60*24*10); ///设置cokiepath(只要访问此应用程序,浏览器必须携带这两个cookie) cookie1.setPath(request.getContextPath()); cookie2.setPath(request.getContextPath()); ///响应cookie,浏览器 response.addCookie(cookie1); response.addCookie(cookie2); } ///成功登录,跳转到用户列表页面 response.sendRedirect(request.getContextPath()+"/dept/list"); }else{ ///登录失败,跳转到失败页面 response.sendRedirect(request.getContextPath()+"/error.jsp"); } }}
WelcomeServletpackage com.bjpowernode.oa.web.action;import com.bjpowernode.oa.utils.DBUtil;import jakarta.servlet.ServletException;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.*;import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;///10天内免登录欢迎页 48@WebServlet("/welcome")public class WelcomeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ///先获得cookie 如果不是null,这个cokie[]数组可能是null,数组的长度必须大于0 Cookie[] cookies = request.getCookies();///获得cookie数组 String username = null; String password = null; if (cookies != null) (//如果cookie不是nullil, for (Cookie cookie : cookies) (///循环遍历cookie数组 String name = cookie.getName();///先得到cookiename,然后得到value //因有两个cookie,因此,根据不同的cookiename获得不同的value if("username".equals(name)){ username = cookie.getValue(); }else if("password".equals(name)){ password = cookie.getValue(); } } } //在这里使用username和pasword变量 if(username != null && password != null){ ////验证用户名和密码是否正确 Connection conn =null; PreparedStatement ps = null; ResultSet rs = null; boolean success = false; try { conn = DBUtil.getConnection(); String sql = "select * from t_user where username = ? and password = ?"; ps = conn.prepareStatement(sql); ps.setString(1,username); ps.setString(2,password); rs = ps.executeQuery(); if(rs.next()){ ///成功登录 success = true; } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn,ps,rs); } if(success){ ///获得session对象 HttpSession session = request.getSession(); session.setAttribute("username",username); //正确,意味着登录成功 response.sendRedirect(request.getContextPath()+"/dept/list"); }else{ //错误,表示登录失败 response.sendRedirect(request.getContextPath()+"/index.jsp"); } }else{ //跳转登录页面 ///这里使用重定向 response.sendRedirect(request.getContextPath()+"/index.jsp"); } }}
SRC配置文件.resourcesjdbc.propertiesdriver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/bjpowernodeuser=rootpassword=lzl
web.xml<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="https://www.tulingxueyuan.cn/d/file/p/20230602/ttxjb54axo2" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"><!-- 欢迎页面配置 48--> <welcome-file-list> <welcome-file>welcome</welcome-file> </welcome-file-list></web-app>
index.jsp<%@page contentType="text/html;charset=UTF-8"%><%--更改jsp 38 将此页面改为登录页面 41--%><%--访问jsp时,不生成sesssion对象 44--%><%@page session="false" %><!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>OA系统欢迎使用</title> </head> <body> <%-- 当前端发送请求路径时,如果要求路径是绝对路径,则应使用 / 开始,添加项目名称。--%> <%-- 这样写代码,oa项目名写死了。--%> <%-- 这样写代码,oa项目名写死了。这种设计显然不好。--%> <%-- <a href="/oa/list.jsp">查看部门列表</a>--%> <%-- <a href="<%=request.getContextPath()%>/list.jsp">查看部门列表</a>--%> <%-- 执行Servlet,查询数据库,收集数据--%> <%-- <a href="<%=request.getContextPath() %>/dept/list">查看部门列表</a>--%> <%-- <hr>--%> <%-- 调用方法获取应用的根路径-%> <%-- <%=request.getContextPath()%> <%–类似out.print(request.getContextPath()); –%>--%><%-- 绘制用户登录页面 41--%> <h1>用户登录</h1> <hr> <form action = "<%=request.getContextPath()%>/user/login" method="post"> username:<input type="text" name="username"/><br> password:<input type="password" name="password"/><br> <input type="checkbox" name="f" value="1"/>十天内免登录<br> <input type="submit" value="login"/> </form> </body></html>
list.jsp<%@ page import="com.bjpowernode.oa.bean.Dept" %><%@ page import="java.util.List" %><%@page contentType="text/html;charset=UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>部门列表页面</title></head><body><%--显示一个登录名 44--%><h3>欢迎<%=request.getSession().getAttribute("username")%></h3><%--写一个安全退出的功能 45--%><a href="<%=request.getContextPath()%>/user/exit">[退出系统]</a><script type="text/javascript">function del(dno){//弹出确认框,用户点击确定,返回true,点击取消返回falsevarr ok = window.confirm("亲,删除不可恢复哦”);if(ok)如何在js代码中向服务器发送请求///发送请求进行删除数据操作////document.location.href = “请求路径”//document.location = “请求路径”//window.location.href = “请求路径”//window.location = “请求路径”document.location.href="<%=request.getContextPath()%>/dept/delete?deptno="+dno}}</script><h1 align="center">部门列表</h1><hr ><table border="1px" align="center" width="50%"><tr><th>序号</th><th>部门编号</th><th>部门名称</th><th>操作</th></tr><%///从request域中取出数据Listt<Dept> deptList = (List<Dept>)request.getAttribute("depList");///循环遍历int i = 0;for(Dept dept:deptList)后台输出System{/.out.println(dept.getDname());////输出部名称到浏览器////out.write(dept.getDname());///以下红线报错是idea没事就别出来了。不影响%><tr><td><%=++i%></td><td><%=dept.getDeptno()%></td><td><%=dept.getDname()%></td><td><a href="javascript:void(0)" onclick="del(<%=dept.getDeptno()%>)">删除</a><a href="<%=request.getContextPath()%>/dept/detail?f=edit&dno=<%=dept.getDeptno()%>">修改</a><a href="<%=request.getContextPath()%>/dept/detail?f=detail&dno=<%=dept.getDeptno()%>">详情</a></td></tr><%}%></table><hr ><a href="<%=request.getContextPath()%>/add.jsp">新增部门</a></body></html>
add.jsp<%@page contentType="text/html;charset=UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>新增部门</title></head><body><%--显示一个登录名 44--%><h3>欢迎<%=request.getSession().getAttribute("username")%></h3><h1>新增部门</h1><hr ><form action="<%=request.getContextPath()%>/dept/save" method="post">部门编号<input type="text" name="deptno"/><br>部门名称<input type="text" name="dname"/><br>部门位置<input type="text" name="loc"/><br><input type="submit" value="保存"/><br></form></body></html>
detail.jsp<%@ page import="com.bjpowernode.oa.bean.Dept" %><%@page contentType="text/html;charset=UTF-8"%><%///从request域中取出数据 39Dept d = (Dept) request.getAttribute("dept");%><!DOCTYPE html><html><head><meta charset="utf-8"><title>部门详情</title></head><body><%--显示一个登录名 44--%><h3>欢迎<%=request.getSession().getAttribute("username")%></h3><h1>部门详情</h1><hr >部门编号:<%=d.getDeptno()%> <br>部门名称:<%=d.getDname()%><br>部门位置:<%=d.getLoc()%><br><input type="button" value="后退" onclick="window.history.back()"/></body></html>
edit.jsp<%@ page import="com.bjpowernode.oa.bean.Dept" %><%@page contentType="text/html;charset=UTF-8"%><%///从request域中取出数据 40Dept d = (Dept) request.getAttribute("dept");%><!DOCTYPE html><html><head><meta charset="utf-8"><title>修改部门</title></head><body><%--显示一个登录名 44--%><h3>欢迎<%=request.getSession().getAttribute("username")%></h3><h1>修改部门</h1><hr ><form action="<%=request.getContextPath()%>/dept/modify" method="post">部门编号<input type="text" name="deptno" value="<%=d.getDeptno()%>" readonly /><br>部门名称<input type="text" name="dname" value="<%=d.getDname()%>"/><br>部门位置<input type="text" name="loc" value="<%=d.getLoc()%>"/><br><input type="submit" value="修改"/><br></form></body></html>
error.jsp<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>登录失败</title></head><body><%--登录失败页面 41--%>登陆失败,请<a href="<%=request.getContextPath()%>/index.jsp">重新登录</a></body></html>