老杜 JavaWeb 讲解(十一) —— 使用纯粹的Servlet做一个单表的CRUD操作

发布时间 2023-07-20 18:24:45作者: 猪无名

(十二)使用纯粹的Servlet做一个单表的CRUD操作

对应视频:

26-设计数据库表以及原型

实现步骤

使用纯粹的Servlet完成单表【对部门的】的增删改查操作。(B/S结构的。)

第一步:准备一张数据库表

# 部门表(sql脚本)
drop table if exists dept;
create table dept(
	deptno int primary key,
    dname  varchar(255),
    loc    varchar(255)
);
insert into dept(deptno,dname,loc)values(10,'销售部','北京');
insert into dept(deptno,dname,loc)values(20,'研发部','上海');
insert into dept(deptno,dname,loc)values(30,'技术部','广州');
insert into dept(deptno,dname,loc)values(40,'媒体部','深圳');
commit;
select * from dept;

第二步:准备一套HTML页面(项目原型)

前端开发工具使用HBuilder。

  • 把HTML页面准备好
  • 然后将HTML页面中的链接都能够跑通。(页面流转没问题。)
  • 应该设计哪些页面呢?
    • 欢迎页面:index.html
    • 列表页面:list.html(以列表页面为核心,展开其他操作。)
    • 新增页面:add.html
    • 修改页面:edit.html
    • 详情页面:detail.html

第三步:分析我们这个系统包括哪些功能?

  • 什么叫做一个功能呢?
    • 只要 这个操作连接了数据库,就表示一个独立的功能。

包括哪些功能?

  • 查看部门列表
  • 新增部门
  • 删除部门
  • 查看部门详细信息
  • 跳转到修改页面
  • 修改部门

第四步:在IDEA当中搭建开发环境

①:创建一个webapp,添加jar包支持。
②:向webapp中添加连接数据库的jar包(mysql)
  • 必须在WEB-INF目录下新建lib目录,然后将mysql的驱动jar包拷贝到这个lib目录下。这个目录名必须叫做lib,全部小写的。
③:JDBC的工具类
package com.zwm.oa.utils;

import java.sql.*;
import java.util.ResourceBundle;
import java.util.Stack;

/**
 * @author 猪无名
 * @date 2023/7/14 16 15
 * discription:JDBC的工具类
 */
public class DBUtil {
    //静态变量:在类加载时,执行
    //顺序:自上而下

    //属性资源文件绑定,根据属性配置文件的key获取value。
    private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
    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数据库。
            //如果直接写死,后续更改可能要修改java代码,显然违背OCP原则(对扩展开放,对修改关闭)。
            //Class.forName("com.mysql.jdbc.Driver");
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取数据库连接对象
     * @return connection连接对象
     * @throws SQLException
     */
    public static Connection getConnection()  throws SQLException {
        //注册驱动只需要注册一次, 因此放在静态代码块中。
        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);

        return connection;
    }

    /**
     *释放资源
     * @param connection     连接对象
     * @param statement      数据库操作对象
     * @param resultSet      结果集对象
     */
    public static void close(Connection connection, Statement statement, ResultSet resultSet){
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

第五步:实现第一个功能(查看部门列表)

我们应该怎么去实现一个功能呢?

  • 建议:你可以从后端往前端一步一步写。也可以从前端一步一步往后端写。都可以。但是千万要记住不要想起来什么写什么。你写代码的过程最好是程序的执行过程。也就是说:程序执行到哪里,你就写哪里。这样一个顺序流下来之后,基本上不会出现什么错误、意外。
流程举例:
  1. 先修改前端页面的超链接,因为用户先点击的就是这个超链接。
<a href="/oa/dept/list">查看部门列表</a>
/oa				项目名
/dept/list      资源路径
  1. 编写web.xml文件
<servlet>
    <servlet-name>list</servlet-name>
    <servlet-class>com.bjpowernode.oa.web.action.DeptListServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>list</servlet-name>
    <!--web.xml文件中的这个路径也是以“/”开始的,但是不需要加项目名-->
    <url-pattern>/dept/list</url-pattern>
</servlet-mapping>
  1. 编写DeptListServlet类继承HttpServlet类。然后重写doGet方法。
package com.zwm.oa.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * @author 猪无名
 * @date 2023/7/14 17 12
 * discription:
 */
public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
    }
}
  1. 在DeptListServlet类的doGet方法中连接数据库,查询所有的部门,动态的展示部门列表页面.
  • 分析list.html 页面中哪些部分是固定死的,哪些部分是需要动态展示的。
  • list.html中的内容所有的双引号都要替换为单引号,因为out.print(""); 这里有一个双引号,容易起冲突。
package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author 猪无名
 * @date 2023/7/14 17 12
 * discription:
 */
public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        //在html页面中,固定不变的。
        out.print("<!DOCTYPE html>");
        out.print("<html>");
        out.print("   <head>");
        out.print("      <meta charset='utf-8'>");
        out.print("      <title>部门列表页面</title>");
        out.print("   </head>");
        out.print("   <body>");
        out.print("      <h1 align='center'>部门列表</h1>");
        out.print("      <hr>");
        out.print("      <table border='1px' align='center' width='50%'>");
        out.print("         <tr>");
        out.print("            <th>序号</th>");
        out.print("            <th>部门编号</th>");
        out.print("            <th>部门名称</th>");
        out.print("            <th>操作</th>");
        out.print("         </tr>");
        out.print("         ");


        //连接数据库所需变量
        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);
            //执行SQL语句
            rs = ps.executeQuery();

            //处理结果集
            int number = 0;
            while(rs.next()){
                String deptno = rs.getString("deptno");
                String dname = rs.getString("dname");
                String loc = rs.getString("loc");



                out.print("         <tr>");
                out.print("            <td>"+(++number)+"</td>");
                out.print("            <td>"+deptno+"</td>");
                out.print("            <td>"+dname+"</td>");
                out.print("            <td>");
                out.print("               <a href=''>删除</a>");
                out.print("               <a href='edit.html'>修改</a>");
                out.print("               <a href='detail.html'>详情</a>");
                out.print("            </td>");
                out.print("         </tr>");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }

        //在html页面中,固定不变的。
        out.print("      </table>");
        out.print("      ");
        out.print("      <hr>");
        out.print("      <a href='add.html'>新增部门</a>");
        out.print("   </body>");
        out.print("</html>");

    }
}
  • 只使用servlet写代码太繁琐了。

第六步:查看部门详情

  • 建议:从前端往后端一步一步实现。首先要考虑的是,用户点击的是什么?用户点击的东西在哪里?
  • 找到对应的超链接,进行相应的更改
out.print("<a href='"+contextPath+"/dept/detail?deptno="+deptno+"'>详情</a>");
  • 重点:向服务器提交数据的格式:uri?name=value&name=value&name=value&name=value

  • 这里的问号,必须是英文的问号。不能中文的问号。

编写xml文件:

<servlet>
    <servlet-name>detail</servlet-name>
    <servlet-class>com.zwm.oa.action.DeptDetailServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>detail</servlet-name>
    <url-pattern>/dept/detail</url-pattern>
</servlet-mapping>

编写一个类:DeptDetailServlet继承HttpServlet,重写doGet方法。

public class DeptDetailServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //中文思路(思路来源于:你要做什么?目标:查看部门详细信息。)
        // 第一步:获取部门编号
        // 第二步:根据部门编号查询数据库,获取该部门编号对应的部门信息。
        // 第三步:将部门信息响应到浏览器上。(显示一个详情。)
    }
}

具体代码:

在doGet方法当中:连接数据库,根据部门编号查询该部门的信息。动态展示部门详情页。

package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author 猪无名
 * @date 2023/7/14 19 34
 * discription:
 */
public class DeptDetailServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.print("<!DOCTYPE html>");
        out.print("<html>");
        out.print("	<head>");
        out.print("		<meta charset='utf-8'>");
        out.print("		<title>部门详情</title>");
        out.print("	</head>");
        out.print("	<body>");
        out.print("		<h1>部门详情</h1>");
        out.print("		<hr>");

        String deptno = request.getParameter("deptno");
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = DBUtil.getConnection();
            //获取预处理的数据库操作对象
            String sql = "select deptno,dname,loc from dept where deptno = ?";
            ps=conn.prepareStatement(sql);
            ps.setString(1,deptno);

            //执行SQL语句
            rs = ps.executeQuery();
            if(rs.next()){
                String dname = rs.getString("dname");
                String loc = rs.getString("loc");

                out.print("                部门编号:"+deptno+"			<br>");
                out.print("                部门名称:"+dname+"			<br>");
                out.print("                部门位置:"+loc+"		<br>");

            }
            
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }

        out.print("		<input type='button' value='后退' onclick='window.history.back()'/>");
        out.print("		");
        out.print("	</body>");
        out.print("</html>");
    }
}

第七步:删除部门

怎么开始?从哪里开始?从前端页面开始,用户点击删除按钮的时候,应该提示用户是否删除。因为删除这个动作是比较危险的。任何系统在进行删除操作之前,是必须要提示用户的,因为这个删除的动作有可能是用户误操作。(在前端页面上写JS代码,来提示用户是否删除。)

<script type="text/javascript">
    function del(dno){
        if(window.confirm("亲,删了不可恢复哦!")){
            document.location.href = "/oa/dept/delete?deptno=" + dno;
        }
    }
</script>

javascript:void(0) 是一个特殊的 JavaScript 语法,它通常用于在 HTML 中创建无操作的超链接。当用户点击这样的超链接时,不会触发任何具体的操作。这种语法经常用于占位符链接或者在 HTML 中使用 JavaScript 来执行其他操作。

只是为了点击超链接的时候执行一段JS代码而不希望进行页面跳转。

以上的前端程序需要写到后端的java代码当中:

  • DeptListServlet类的doGet方法当中,使用out.print()方法,将以上的前端代码输出到浏览器上,只有这样才会生效。

更改xml文件:

<servlet>
    <servlet-name>delete</servlet-name>
    <servlet-class>com.zwm.oa.action.DeptDeleteServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>delete</servlet-name>
    <url-pattern>/dept/delete</url-pattern>
</servlet-mapping>

更改之后的代码(DeptListServlet.java):

package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author 猪无名
 * @date 2023/7/14 17 12
 * discription:
 */
public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取应用的根路径
        String contextPath = request.getContextPath();

        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        //在html页面中,固定不变的。
        out.print("<!DOCTYPE html>");
        out.print("<html>");
        out.print("   <head>");
        out.print("      <meta charset='utf-8'>");
        out.print("      <title>部门列表页面</title>");

        
		out.print("   <script type='text/javascript'>");
        out.print("           function del(dno){");
        out.print("       if(window.confirm('亲,删了不可恢复哦!')){");
        out.print("           document.location.href = '"+contextPath+"/dept/delete?deptno=' + dno;");
        out.print("       }");
        out.print("   }");
		out.print("   </script>");

        

        out.print("   </head>");
        out.print("   <body>");
        out.print("      <h1 align='center'>部门列表</h1>");
        out.print("      <hr>");
        out.print("      <table border='1px' align='center' width='50%'>");
        out.print("         <tr>");
        out.print("            <th>序号</th>");
        out.print("            <th>部门编号</th>");
        out.print("            <th>部门名称</th>");
        out.print("            <th>操作</th>");
        out.print("         </tr>");


        //连接数据库所需变量
        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);
            //执行SQL语句
            rs = ps.executeQuery();


            int number = 0;
            //处理结果集
            while(rs.next()){
                String deptno = rs.getString("deptno");
                String dname = rs.getString("dname");
                String loc = rs.getString("loc");



                out.print("         <tr>");
                out.print("            <td>"+(++number)+"</td>");
                out.print("            <td>"+deptno+"</td>");
                out.print("            <td>"+dname+"</td>");
                out.print("            <td>");
                out.print("               <a href= 'javascript:void(0)' onclick='del("+deptno+")'>删除</a>");
                out.print("               <a href='edit.html'>修改</a>");
                out.print("               <a href='"+contextPath+"/dept/detail?deptno="+deptno+"'>详情</a>");
                out.print("            </td>");
                out.print("         </tr>");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }

        //在html页面中,固定不变的。
        out.print("      </table>");
        out.print("      ");
        out.print("      <hr>");
        out.print("      <a href='add.html'>新增部门</a>");
        out.print("   </body>");
        out.print("</html>");

    }
}

处理删除功能的代码:DeptDeleteServlet.java

package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;

/**
 * @author 猪无名
 * @date 2023/7/15 00 49
 * discription:
 */
public class DeptDeleteServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String deptno = request.getParameter("deptno");


        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = DBUtil.getConnection();
            String sql = "DELETE FROM dept WHERE deptno = ?";
            ps=conn.prepareStatement(sql);
            ps.setString(1,deptno);
            //执行SQL语句
            int rowsAffected = ps.executeUpdate();
            if (rowsAffected > 0) {
                System.out.println("删除成功");
                
                // 删除完成后重定向回原来的页面
                String referer = request.getHeader("Referer");
                response.sendRedirect(referer);

            } else {
                System.out.println("删除失败");
            }

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }
    }
}

删除成功之后,如何跳转回原来的页面?

方法①:转发

request.getRequestDispatcher("/dept/list").forward(request, response);

方法②:重定向

String referer = request.getHeader("Referer");
response.sendRedirect(referer);
  1. String referer = request.getHeader("Referer");request 对象是由 Servlet 容器传递给 Servlet 的,它包含了当前请求的相关信息。getHeader("Referer") 方法用于获取客户端请求的 "Referer" 头部字段的值,并将其存储在 referer 变量中。
  2. response.sendRedirect(referer);response 对象是 Servlet 容器提供的,用于与客户端进行通信。sendRedirect() 方法接受一个字符串参数,即重定向的目标 URL。在这里,我们将 referer 变量作为参数传递给 sendRedirect() 方法,将用户重定向回原来的页面。

第八步:新增部门

修改部分代码:

out.print("      <a href='"+contextPath+"/dept/add'>新增部门</a>");
out.print("      <a href='"+contextPath+"/add. html'>新增部门</a>");

两种方式,继续跳转到Servlet或者html页面,在上面提交信息即可。

注意:此处的增加并没有进行排重,也就是说会出现主键重复报错的情况,可以通过查询来避免,但是写起来很麻烦,放到后面讲更好的解决方法。

代码:

package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
   
public class DeptAddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取应用的根路径
        String contextPath = request.getContextPath();
        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.print("   <!DOCTYPE html>");
        out.print("   <html>");
        out.print("   	<head>");
        out.print("   		<meta charset='utf-8'>");
        out.print("   		<title>新增部门</title>");
        out.print("   	</head>");
        out.print("   	<body>");
        out.print("   		<h1>新增部门</h1>");
        out.print("   		<hr>");
        out.print("   		<form action='"+contextPath+"/dept/JDBCadd' method='get'>");
        out.print("                  部门编号:<input type='text' name='deptno'/><br>");
        out.print("                  部门名称:<input type='text' name='deptname'/><br>");
        out.print("                  部门位置:<input type='text' name='loc'/><br>");
        out.print("   			<input type='submit' value='提交'/><br>");
        out.print("   		</form>");
        out.print("   	</body>");
        out.print("   </html>");

    }
}

package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author 猪无名
 * @date 2023/7/15 02 19
 * discription:
 */
public class DeptJDBCAddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String deptno = request.getParameter("deptno");
        String deptname = request.getParameter("deptname");
        String loc = request.getParameter("loc");
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = DBUtil.getConnection();
            String sql = "INSERT INTO dept (deptno, dname, loc) VALUES (?, ?, ?)";
            ps=conn.prepareStatement(sql);
            ps.setString(1,deptno);
            ps.setString(2,deptname);
            ps.setString(3,loc);
            //执行SQL语句
            //返回值代表影响了数据库当中多少条数据。
            int rowsAffected = ps.executeUpdate();
            if (rowsAffected > 0) {
                System.out.println(rowsAffected + " 行已插入数据");
                request.getRequestDispatcher("/dept/list").forward(request, response);
            } else {
                System.out.println("未插入任何数据");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }
    }
}

第八步:修改部门

思路:

①:找到进入更改的超链接,给出对应的跳转路径。
out.print("<a href='"+contextPath+"/dept/update?deptno="+deptno+"&dname="+dname+"&loc="+loc+"'>修改</a>");

通过get请求传参数。

②:写接收显示代码,供用户修改提交数据。
package com.zwm.oa.action;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author 猪无名
 * @date 2023/7/20 16 39
 * discription:
 */
public class DeptUpdateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取应用的根路径
        String contextPath = request.getContextPath();

        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String deptno = request.getParameter("deptno");
        String dname = request.getParameter("dname");
        String loc = request.getParameter("loc");


        out.print("    <!DOCTYPE html>");
        out.print("    <html>");
        out.print("       <head>");
        out.print("          <meta charset='utf-8'>");
        out.print("          <title>修改部门</title>");
        out.print("       </head>");
        out.print("       <body>");
        out.print("          <h1>修改部门</h1>");
        out.print("          <hr>");
        out.print("          <form action='"+contextPath+"/dept/JDBCupdate' method='get'>");
        out.print("部门编号:<input type='text' name='deptno' value='"+deptno+"' readonly/><br>");
        out.print("部门名称:<input type='text' name='deptname' value='"+dname+"'/><br>");
        out.print("部门位置:<input type='text' name='loc' value='"+loc+"'/><br>");
        out.print("             <input type='submit' value='修改'/><br>");
        out.print("          </form>");
        out.print("       </body>");
        out.print("    </html>");

    }
}

③JDBC操作代码
package com.zwm.oa.action;

import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author 猪无名
 * @date 2023/7/20 16 43
 * discription:
 */
public class DeptJDBCUpdateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置相应内容类型和字符集,防止中文乱码。
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String deptno = request.getParameter("deptno");
        String deptname = request.getParameter("deptname");
        String loc = request.getParameter("loc");

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = DBUtil.getConnection();

            String sql = "UPDATE dept SET dname = ?, loc = ? WHERE deptno = ?";

            ps=conn.prepareStatement(sql);

            ps.setString(1,deptname);
            ps.setString(2,loc);
            ps.setString(3,deptno);
            //执行SQL语句
            //返回值代表影响了数据库当中多少条数据。
            int rowsAffected = ps.executeUpdate();

            if (rowsAffected > 0) {
                System.out.println("更改成功");

                request.getRequestDispatcher("/dept/list").forward(request, response);

            } else {
                System.out.println("无匹配数据");
            }

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }

    }
}