1. 分析使用纯粹Servlet开发web应用的缺陷 35
1.1 在Servlet当中编写HTML/CSS/JavaScript等前端代码。存在什么问题? 35
- java程序中编写前端代码,编写难度大。麻烦。
- java程序中编写前端代码,显然程序的耦合度非常高。
- java程序中编写前端代码,代码非常不美观。
- java程序中编写前端代码,维护成本太高。(非常难于维护)
- 修改小小的一个前端代码,只要有改动,就需要重新编译java代码,生成新的class文件,打一个新的war包,重新发布。
1.2 思考一下,如果是你的话,你准备怎么解决这个问题?35
- 思路很重要。使用什么样的思路去做、去解决这个问题
- 上面的那个Servlet(Java程序)能不能不写了,让机器自动生成。我们程序员只需要写这个Servlet程序中的“前端的那段代码”,然后让机器将我们写的“前端代码”自动翻译生成“Servlet这种java程序”。然后机器再自动将“java”程序编译生成"class"文件。然后再使用JVM调用这个class中的方法。
2. 知识点
2.1 思考一个问题:如果我只用JSP这一个技术,能不能开发web应用? 39
- 当然可以使用JSP来完成所有的功能。因为JSP就是Servlet,在JSP的<%%>里面写的代码就是在service方法当中的,所以在<%%>当中完全可以编写JDBC代码,连接数据库,查询数据,也可以在这个方法当中编写业务逻辑代码,处理业务,都是可以的,所以使用单独的JSP开发web应用完全没问题。
- 虽然JSP一个技术就可以完成web应用,但是不建议,还是建议采用servlet + jsp的方式进行开发。这样都能将各自的优点发挥出来。JSP就是做数据展示。Servlet就是做数据的收集。(JSP中编写的Java代码越少越好。)一定要职责分明。
2.2 JSP文件的扩展名必须是xxx.jsp吗? 39
- jsp文件的扩展名是可以配置的。不是固定的。
- 在CATALINA_HOME/conf/web.xml,在这个文件当中配置jsp文件的扩展名。
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
- xxx.jsp文件对于小猫咪来说,只是一个普通的文本文件,web容器会将xxx.jsp文件最终生成java程序,最终调用的是java对象相关的方法,真正执行的时候,和jsp文件就没有关系了。
- 小窍门:JSP如果看不懂,建议把jsp翻译成java代码,就能看懂了。
2.3 包名bean是什么意思? 39
- javabean(java的logo是一杯冒着热气的咖啡。javabean被翻译为:咖啡豆)
- java是一杯咖啡,咖啡又是由一粒一粒的咖啡豆研磨而成。
- 整个java程序中有很多bean的存在。由很多bean组成。
2.3.1 什么是javabean?
实际上javabean你可以理解为符合某种规范的java类,比如:
- 有无参数构造方法
- 属性私有化
- 对外提供公开的set和get方法
- 实现java.io.Serializable接口
- 重写toString
- 重写hashCode+equals
- ....
- javabean其实就是java中的实体类。负责数据的封装。
- 由于javabean符合javabean规范,具有更强的通用性。
4. 使用Servlet + JSP完成oa项目的改造。 38
4.1 使用Servlet处理业务,收集数据。 使用JSP展示数据。38
- 将之前原型中的html文件,全部修改为jsp,然后在jsp文件头部添加page指令(指定contentType防止中文乱码),将所有的JSP直接拷贝到web目录下。
- 完成所有页面的正常流转。(页面仍然能够正常的跳转。修改超链接的请求路径。)
- <%=request.getContextPath() %> 在JSP中动态的获取应用的根路径。
4.2 Servlet中连接数据库,查询所有的部门,遍历结果集。39
- 遍历结果集的过程中,取出部门编号、部门名、位置等信息,封装成java对象。
- 将java对象存放到List集合中。
- 将List集合存储到request域当中。
- 转发forward到jsp。
4.2.1 在JSP中: 39
- 从request域当中取出List集合。
- 遍历List集合,取出每个部门对象。动态生成tr。
4.3 当前的oa应用存在的问题: 41
- 任何一个用户都可以访问这个系统,都可以对这个系统当中的数据进行增删改这些危险的操作。我只想让合法的用户去使用这个系统,不合法的用户不能访问这个系统,怎么办?
- 加一个登录功能。登录成功的可以访问该系统,登录失败不能访问。
4.3.1 实现登录功能:41
4.3.1.1 步骤1:数据库当中添加一个用户表:t_user 41
- t_user表当中存储的是用户的登录信息,最基本的也包括:登录的用户名和登录的密码。
- 密码一般在数据库表当中存储的是密文。一般不以明文的形式存储。(这里先使用明文方式。)
- 向t_user表中插入数据。
4.3.1.2步骤2:再实现一个登录页面。 41
- 登录页面上应该有一个登录的表单。有用户名和密码输入的框。
- 用户点击登录,提交表单,提交用户名和密码。form是post方式提交。
4.3.1.3 步骤3:后台要有一个对应的Servlet来处理登录的请求。 41
- 登录成功:跳转到部门列表页面。
- 登录失败:跳转到失败的页面。
4.3.1.4 步骤4:再提供一个登录失败的页面。 41
- 登录功能实现了,目前存在的最大的问题:
- 这个登录功能目前只是一个摆设,没有任何作用。只要用户知道后端的请求路径,照样可以在不登录的情况下访问。
- 这个登录没有真正起到拦截的作用。怎么解决?
- JSP的指令
- 指令的作用:指导JSP的翻译引擎如何工作(指导当前的JSP翻译引擎如何翻译JSP文件。)
- 指令包括哪些呢?
- include指令:包含指令,在JSP中完成静态包含,很少用了。(这里不讲)
- taglib指令:引入标签库的指令。这个到JJSTL标签库的时候再学习。现在先不管。
- page指令:目前重点学习一个page指令。
- 指令的使用语法是什么?
- <%@指令名 属性名=属性值 属性名=属性值 属性名=属性值....%>
代码在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 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 {
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);
}
}
//保存部门信息 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.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
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")
public class UserServlet extends HttpServlet {
@Override
protected void doPost(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){
//登陆成功,跳转到用户列表页面
response.sendRedirect(request.getContextPath()+"/dept/list");
}else{
//登录失败,跳转到失败页面
response.sendRedirect(request.getContextPath()+"/error.jsp");
}
}
}
javabean com.bjpowernode.oa.bean
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();
}
}
}
}
配置文件 src.resources
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=lzl
index.jsp
<%@page contentType="text/html;charset=UTF-8"%>
<%--进行jsp更改 38 把这个页面改成登录页面 41--%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>欢迎使用OA系统</title>
</head>
<body>
<%-- 前端发送请求路径的时候,如果请求路径是绝对路径,要以 / 开始,加项目名。--%>
<%-- 以下这样写代码,oa项目名写死了。这种设计显然是不好的。--%>
<%-- <a href="https://www.ctyun.cn/portal/link.html?target=%2Foa%2Flist.jsp">查看部门列表</a>--%>
<%-- <a href="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29%25%26gt%3B%2Flist.jsp">查看部门列表</a>--%>
<%-- 执行一个Servlet,查询数据库,收集数据--%>
<%-- <a href="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29+%25%26gt%3B%2Fdept%2Flist">查看部门列表</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="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>
<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="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29%25%26gt%3B%2Fdept%2Fdelete%3Fdeptno%3D"+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="https://www.ctyun.cn/portal/link.html?target=javascript%3Avoid%280%29" onclick="del(<%=dept.getDeptno()%>)">删除</a>
<a href="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29%25%26gt%3B%2Fdept%2Fdetail%3Ff%3Dedit%26amp%3Bdno%3D%26lt%3B%25%3Ddept.getDeptno%28%29%25%26gt%3B">修改</a>
<a href="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29%25%26gt%3B%2Fdept%2Fdetail%3Ff%3Ddetail%26amp%3Bdno%3D%26lt%3B%25%3Ddept.getDeptno%28%29%25%26gt%3B">详情</a>
</td>
</tr>
<%
}
%>
</table>
<hr >
<a href="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29%25%26gt%3B%2Fadd.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>
<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>
<h1>部门详情</h1>
<hr >
部门编号:<%=d.getDeptno()%> <br>
部门名称:<%=d.getDname()%><br>
部门位置:<%=d.getLoc()%><br>
<input type="button" value="后退" onclick="window.history.back()"/>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
<%--登录失败页面 41--%>
登陆失败,请<a href="https://www.ctyun.cn/portal/link.html?target=%26lt%3B%25%3Drequest.getContextPath%28%29%25%26gt%3B%2Findex.jsp">重新登录</a>
</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>
<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>
添加 数据库的t_user的sql脚本 在E:\java\course19\t_user 41
t_user.sql
drop table if exists t_user;
CREATE TABLE t_user(
id INT PRIMARY KEY auto_increment,
username VARCHAR(255),
password VARCHAR(255)
);
INSERT INTO t_user(username,password) VALUES('admin','123456');
INSERT INTO t_user(username,password) VALUES('zhangsan','123456');
commit;
SELECT *FROM t_user;