1. session掌握之后,我们怎么解决oa项目中的登录问题,怎么能让登录起作用。 44
1.1 思路 44
- 登录成功之后,可以将用户的登录信息存储到session当中。也就是说session中如果有用户的信息就代表用户登录成功了。session中没有用户信息,表示用户没有登录过。则跳转到登录页面。
- 销毁session对象: 45
session.invalidate();
2. 使用cookie实现一下十天内免登录功能。48
- 先实现登录功能
- 登录成功
- 跳转到部门列表页面
- 登录失败
- 跳转到登录失败页面
- 修改前端页面
- 在登录页面给一个复选框,复选框后面给一句话:十天内免登录。
- 用户选择了复选框:表示要支持十天内免登录。
- 用户没有选择复选框:表示用户不想使用十天内免登录功能。
- 修改Servlet中的login方法
- 如果用户登录成功了,并且用户登录时选择了十天内免登录功能,这个时候应该在Servlet的login方法中创建cookie,用来存储用户名和密码,并且设置路径,设置有效期,将cookie响应给浏览器。(浏览器将其自动保存在硬盘文件当中10天)
- 用户再次访问该网站的时候,访问这个网站的首页的时候,有两个走向:
- 要么跳转到部门列表页面
- 要么跳转到登录页面
- 以上分别有两个走向,这显然是需要编写java程序进行控制的。
3.代码
代码在com.bjpowernode.oa.bean.
javabean Dept
package 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
工具类DBUtil
package 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.action
DeptServlet
package 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,获取不到这返回null
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);
//获取不同的标识(这个标识是我们再list.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 = ? 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");
}
}
}
UserServlet
package 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){
//手动销毁session对象
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=?";
//编译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对象一定不为空null
session.setAttribute("username",username);//将用户名存入
//登陆成功了,并且用户选择了十天内免登录
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);
//设置cookie的path(只要访问这个应用,浏览器就一定携带这两个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");
}
}
}
WelcomeServlet
package 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;
//十天内免登录欢迎页 48
@WebServlet("/welcome")
public class WelcomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//先获取cookie
//这个cookie[]数组可能是null,如果不是null,数组的长度一定是大于0的
Cookie[] cookies = request.getCookies();//得到cookie数组
String username = null;
String password = null;
if (cookies != null) {//如果cookie不为null
for (Cookie cookie : cookies) {//循环遍历cookie数组
String name = cookie.getName();//先得到cookie的name,然后在得到value
//因为有两个cookie,所以根据不同的cookie的name得到不同的value
if("username".equals(name)){
username = cookie.getValue();
}else if("password".equals(name)){
password = cookie.getValue();
}
}
}
//要在这里使用username和password变量
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.resources
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=lzl
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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时不生成session对象 44--%>
<%@page session="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>欢迎使用OA系统</title>
</head>
<body>
<%-- 前端发送请求路径的时候,如果请求路径是绝对路径,要以 / 开始,加项目名。--%>
<%-- 以下这样写代码,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,点击取消返回false
var 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域中取出数据
List<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域中取出数据 39
Dept 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域中取出数据 40
Dept 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>
标签:ps,String,request,dept,session,cookie,单表,null,response
From: https://blog.51cto.com/u_15784725/6398245