1. 项目说明
介绍: 这里我们使用 纯粹 的 Servlet 完成单表【对部门的】的增删改查操作。(B/S结构的。)
结构图
初始的欢迎页面
部门列表页面
部门详情
修改部门
删除部门:
新增部门:
2. 具体对应的功能的代码实现
2.1 准备工作:
首先我们使用数据库,存储数据,这里我们使用的数据库是 MYSQL 。
我们需要准备一个名为 dept的数据表,并插入一些数据。
create table dept (depton int primary key, dname varchar(255), loc varchar(255));insert into dept(depton,dname,loc) values(10,&39;,&39;);insert into dept(depton,dname,loc) values(20,&39;,&39;);insert into dept(depton,dname,loc) values(30,&39;,&39;);insert into dept(depton,dname,loc) values(40,&39;,&39;);select * from dept;
小技巧: MySQL 在 cmd 命令中,批量执行 sql语句的方法:如下,首先将编写好的 .sql 文件存储起来。如下图所示。
再打开cmd 进入命令窗口,再进入到Mysql当中,输入如下命令:
source 后接文件路径(要执行的批量的.sql文件)
1、规则动词在词尾加“ed”2、若词尾已有字母e,则只加d 3、若以“辅音+y”结尾,变y为i再加ed 4、若以“元音+辅音”结尾,单音节词则双写辅音字母,再加ed(例:stop→stopped);双音节词只有在第二音节重读时,双写。
当前数据表 dept 的信息内容如下:
为该模块导入 MYSQL的 JDBC 的 jar 包。
注意: 因为我们是在 Tomcat 服务器当中部署项目的,所以我们需要在 WEB-INF 的目录下,创建一个名为 lib 的目录文件夹,用来存放相关的 依赖jar 包,注意路径位置不可以修改,目录文件必须为 lib 不然,当你启动的Tocmat 服务器的时候,是无法找到该对应的 依赖jar 包的。具体如下,我们将 Mysql对应的 jdbc jar 包导入其中。
创建一个webapp(给这个webapp添加servlet-api.jar和jsp-api.jar到classpath当中。)
向webapp中添加连接数据库的jar包(mysql驱动)必须在WEB-INF目录下新建lib目录,然后将mysql的驱动jar包拷贝到这个lib目录下。这个目录名必须叫做lib,全部小写的。
问题一:英语中有一种形式叫三单还是单三呀? 单三,第三人称单数,例如:he, she, it,everyone, something, nobody, everything, everybady,nothing,this,that,机构名作主语,不可数名词作主语,数字或字母作主语。
2.2 模块目录结构
2.3 工具类 DBUtil
这里因为我们要连接数据库,所以我们编写一个连接Mysql 数据库的 工具类,这里我们名为一个 DBUtil 的工具类。
这里我们通过读取配置jdbc.properties的配置文件的方式,注册相对应的Mysql驱动 。
如下是相关: jdbc.properties 的配置信息
driver=com.mysql.cj.jdbc.Driverurl=jdbc:mysql://localhost:3306/testuser=rootpassword=123
再编写好相关的:DBUtil 类 ,具体代码的编写内容如下:
package com.RainbowSea.DBUtil;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ResourceBundle;/** * JDBC工具类 */public class DBUtil {// 静态变量,在类加载时执行// 都是一些从 jdbc.properties 读取到的配置文件的信息// 该方法仅仅只会读取 “.properties&34;com/RainbowSea/resources/jdbc&34;driver&34;url&34;user&34;password&34;com.mysql.jdbc.Driver&34;com.mysql.jdbc.Driver")try {Class.forName(driver);// 加载驱动} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}/** * 获取数据库连接 * @return Connection */public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url,user,password);}/** * 关闭连接 * @param connection * @param statement * @param resultSet */public static void close(Connection connection,Statement statement,ResultSet resultSet) {// 注意:分开try,最后使用的资源,优先关闭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);}}}}
2.4 功能一: index.html 该项目的欢迎页面如下:
默认在 web 当中,一个全局配置信息当中,会将名为 index.html 的文件,设置为该项目的欢迎页面。相应的具体内容大家可以移步至 关于Web的欢迎页面的开发设置_ChinaRainbowSea的博客-CSDN博客
<!DOCTYPE html><html lang=&34;><head><meta charset=&34;><title>欢迎使用OA系统</title></head><body><!--注意:对应前端的资源获取基本上都是要加项目名的,并且要&34;开始--><a href=&34;>查看部门列表</a></body></html>
2.5 功能二:部门列表 DeptListServlet
注意:因为我们这里使用的是 纯 Servlet 编写的一个项目,所以在后端想要将相关的 HTML 标签相应到前端浏览器,被浏览器渲染的话,则需要特殊的方法:如下
/ 设置将后端的字符串的 html 标签相应到浏览器端执行处理,并设置相应的字符集编码response.setContentType(&34;);PrintWriter writer = response.getWriter();
思路:
在DeptListServlet类的doGet方法中连接数据库,查询所有的部门,动态的展示部门列表页面.
分析 html 页面中哪部分是固定死的,哪部分是需要动态展示的。
html页面中的内容所有的双引号要替换成单引号,因为out.print(&34;)这里有一个双引号,容易冲突。
现在写完这个功能之后,你会有一种感觉,感觉开发很繁琐,只使用servlet写代码太繁琐了
我们需要连接数据库,从数据库中获取到数据,显示到前端浏览器当中。
注意我们这里上面的 index.html 中是通过超链接的方式,跳转到该 部门列表页面的。超链接是 doGet 请求。
package com.RainbowSea.servlet;import com.RainbowSea.DBUtil.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 DeptListServlet extends HttpServlet {/*说明:这里使用了doGet,和 goPost 的原因是,我们前端的 DeptSaveServlet 的新增部门,的请求是doPost,从 doPost 请求&34;出来的同样是 doPost请求的,而 重定向就是doGet请求了,无论是doPost,doGet请求都是所以这里为了,处理接受到 DeptSaveServlet 的新增部门的 &34;请求,写了一个doPost 请求处理 */// 优化,将转发,替换成了 重定向的机制,(重定向的机制)是自发到浏览器前端的地址栏上的,后自发的执行// 地址栏上是 doGet 请求的,就不需要 doPost 请求了。 /* @Overrideprotected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doGet(request,response); // 调用本身这里的doGet()请求}*//*因为我们前端使用的是 <a>超链接,是goGet请求所以,前后端的请求保持一致。 */@Overrideprotected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {// 设置前端浏览器显示的格式类型,以及编码response.setContentType(&34;);PrintWriter writer = response.getWriter();Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;// 获取到该webapp的项目根路径:也就是在Tomcat 当中设置的访问的项目路径// 注意的是: getContextPath()获取返回的路径是带有 &34;的,所以不要多写了 / String contextPath = request.getContextPath();int i = 0;writer.println(&34;);writer.println(&39;en&34;);writer.println(&34;);writer.println(&39;UTF-8&34;);writer.println(&34;);writer.println(&34;);writer.println(&39;text/javascript&34;);writer.println(&34;);// 弹出确认框,用户点击确定,返回true,点击取消返回falsewriter.println(&39;亲,删了不可恢复哦!&34;);writer.println(&34;);// 发送请求进行删除数据的操作// 在js代码当中如何发送请求给服务// document.location.href=&39;请求路径&34;)// window.location.href = &39;请求路径&34; document.location.href = &34; + contextPath + &39; + dno&34;}&34; }&34;</script >&34;<body>&34;<h1 align=&39;>部门列表</h1>&34; <table border=&39; align=&39; width=&39;>&34;<tr>&34;<th>序号</th>&34; <th>部门编号</th>&34; <th>部门名称</th>&34; </tr>&34;select depton as det,dname,loc from dept&34;det&34;dname&34;loc&34; <tr>&34; <td>&34;</td>&34; <td>&34;</td>&34; <td>&34;</td>&34; <td>&34; <a href=&39; onclick= &34; + det + &39;>删除</a>&34; <a href=&34;+contextPath+&34;+det+&39;>修改</a>&34; <a href=&34; + contextPath + &34; + det + &39;>详情</a>&34; </td>&34; </tr>&34;</table>&34;<hr>&34;<a href=&34; + contextPath + &39;>新增部门</a>&34;</body>&34;</html>");}}
2.6 功能三:查看部门详情 DeptDetailServlet
英语单三变化即“第三人称单数变化”,其实不是人称有变化,而是句子里,因为主语的人称是第三人称单数,导致了谓语动词有变化,要加s 或es。所谓的第三人称是指: 除了你、我、你们、我们、他们,---其余所有单个的,都。
建议:从前端往后端一步一步实现。首先要考虑的是,用户点击的是什么?用户点击的东西在哪里?
一定要先找到用户点的“详情”在哪里。这里我们使用超链接的形式处理
<a href=&39;>详情</a>
详情 是需要连接数据库的,所以这个超链接点击之后也是需要执行一段java代码的。所以要将这个超链接的路径修改一下。
2)以s、x、sh、ch结尾的名词加es:glasses,boxes,brushes,matches.3)以辅音字母加y结尾的名词,变y为i加es:cities,babies,enemies.4)以f或fe结尾的名词,多数变f为v加es:wives,knives.但有些词只加s:roofs,proofs。
注意:修改路径之后,这个路径是需要加项目名的。&34;
技巧:
out.print(&39;&34;/dept/detail?deptno=&34;&34;);
重点:向服务器提交数据的格式:uri?name=value&name=value&name=value&name=value 。这里的问号,必须是英文的问号。不能中文的问号。
思路:
中文思路(思路来源于:你要做什么?目标:查看部门详细信息。)第一步:获取部门编号第二步:根据部门编号查询数据库,获取该部门编号对应的部门信息。第三步:将部门信息响应到浏览器上。(显示一个详情。)
package com.RainbowSea.servlet;import com.RainbowSea.DBUtil.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 DeptDetailServlet extends HttpServlet {// 前端超连接是 doGet()请求@Overrideprotected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {// 设置前端浏览器格式类型和字符集编码response.setContentType(&34;);PrintWriter writer = response.getWriter();Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;//中文思路(思路来源于:你要做什么?目标:查看部门详细信息。)// 第一步:获取部门编号// 第二步:根据部门编号查询数据库,获取该部门编号对应的部门信息。// 第三步:将部门信息响应到浏览器上。(显示一个详情。)// 1.// String deptno = request.getParameter(&34;);// 注意是我们前端提交的数据,建议复制nametry {// 2. 连接数据库,根据部门编号查询数据库// 1.注册驱动,连接数据库connection = DBUtil.getConnection();// 2. 预编译SQL语句,sql要测试String sql = &34;;// ? 占位符preparedStatement = connection.prepareStatement(sql);// 3. 填充占位符,真正执行sql语句preparedStatement.setString(1,deptno);resultSet = preparedStatement.executeQuery();// 4. 处理查询结果集while (resultSet.next()) {String dname = resultSet.getString(&34;);String loc = resultSet.getString(&34;);// 注意将 “双引号转换为单引号,因为在Java当中不可以嵌套多个双引号,除非是字符串的拼接// 所以使用 &34;<body>&34;<h1>部门详情</h1>&34;部门编号: &34; <br>&34;部门名称: &34;<br>&34; 部门位置: &34;<br>&34;<input type=&39; value=&39; onclick=&39;/>&34;</body>&34;</html>");}}
2.7 功能四:删除部门 DeptDelServlet
怎么开始?从哪里开始?从前端页面开始,用户点击删除按钮的时候,英语三单表,应该提示用户是否删除。因为删除这个动作是比较危险的。任何系统在进行删除操作之前,是必须要提示用户的,因为这个删除的动作有可能是用户误操作。(在前端页面上写JS代码,来提示用户是否删除。)
<a href=&34; onclick=&34; >删除</a><script type=&34;> function del(dno){ if(window.confirm(&34;)){ document.location.href = &34; + dno; } }</script>
以上的前端程序要写到后端的java代码当中:DeptListServlet类的doGet方法当中,使用out.print()方法,将以上的前端代码输出到浏览器上。
删除成功或者失败的时候的一个处理(这里我们一开始使用的选择的是转发,后面优化使用的是重定向机制。)
删除成功:我们跳转到部门列表当中。DeptListServlet
删除失败:我们跳转到一个失败的页面当中。这里我们将该失败的页面名为: error.html 页面如下:
<!DOCTYPE html><html lang=&34;><head><meta charset=&34;><title>error</title></head><body><h1> 操作失败: </h1><a href=&39; onclick=&34;>返回</a></body></html>
具体的 Servlet 编写如下
动词的第三人称单数形式(简称单三式)1.一般在词尾加“-s”help-helps make-makes ride-rides know-knows 2.在s z x sh ch 结尾的词在词尾加“-es”push-pushes pass-passes watch-watches wash-washes 3.以“。
package com.RainbowSea.servlet;import com.RainbowSea.DBUtil.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.SQLException;/** * 删除部门 */public class DeptDelServlet extends HttpServlet {/*注意前端是超链接的方式:是get请求 */@Overrideprotected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {response.setContentType(&34;);PrintWriter writer = response.getWriter();request.setCharacterEncoding(&34;);// 思路:/*根据部门编号删除信息,删除成功,跳转回原来的部门列表页面删除失败,跳转删除失败的页面 */Connection connection = null;PreparedStatement preparedStatement = null;// 记录删除数据库的行数int count = 0;// 获取到前端提交的数据String deptno = request.getParameter(&34;);// 连接数据库进行删除操作try {// 1.注册驱动,连接数据库connection = DBUtil.getConnection();// 开启事务(取消自动提交机制),实现可回滚connection.setAutoCommit(false);// 2. 预编译sql语句,sql测试String sql = &34;; // ? 占位符preparedStatement = connection.prepareStatement(sql);// 3. 填充占位符,真正的执行sql语句preparedStatement.setString(1,deptno);// 返回影响数据库的行数count = preparedStatement.executeUpdate();connection.commit();// 手动提交数据} catch (SQLException e) {// 遇到异常回滚if (connection != null) {try {// 事务的回滚connection.rollback();} catch (SQLException ex) {throw new RuntimeException(ex);}}throw new RuntimeException(e);} finally {// 4. 释放资源// 因为这里是删除数据,没有查询操作,所以 没有 ResultSet 可以传nullDBUtil.close(connection,preparedStatement,null);}if (count == 1) {// 删除成功// 仍然跳转到部门列表页面// 部门列表页面的显示需要执行另外一个Servlet,怎么办,可以使用跳转,不过这里最后是使用重定向// 注意:转发是在服务器间的,所以不要加“项目名” 而是 / + web.xml 映射的路径即可//request.getRequestDispatcher(&34;).forward(request,response);// 优化:使用重定向机制 注意: 重定向是自发到前端的地址栏上的,前端所以需要指明项目名// 注意: request.getContextPath() 返回的根路径是,包含了 &34; 的response.sendRedirect(request.getContextPath() + &34;);} else {// 删除失败// web当中的 html资源,这里的 &34; 表示 web 目录//request.getRequestDispatcher(&34;).forward(request,response);// 优化,使用重定向response.sendRedirect(request.getContextPath() + &34;);}}}
2.8 功能五:新增部门 DeptSaveServlet
思路:
获取到前端 form 表单提交的数据,这里我们 form 表单 中的 metod = post 设置为了 doPost 请求。
再连接数据库,添加一条记录。
添加成功:我们跳转到部门列表当中。DeptListServlet
添加失败:我们跳转到一个失败的页面当中。这里我们将该失败的页面名为: error.html
注意点:
而同时:这时候接收该 转发 的 /dept/list Servlet当中只有一个doGet方法。就会报 405 错误。
怎么解决?两种方案
第一种:在/dept/list Servlet中添加doPost方法,然后在doPost方法中调用doGet。第二种:使用重定向的方式,进行跳转,重定向的机制是改变浏览器的请求路径URL,让浏览器重新发送跳转之后的 URL 地址,该方式是从浏览器地址栏上跳转的,所以是 doGet 请求,就不要编写 doPost 请求了。
具体代码编写如下:
package com.RainbowSea.servlet;import com.RainbowSea.DBUtil.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.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;/** * 增加部门数据 */public class DeptSaveServlet extends HttpServlet {// 前端是注册信息,是post 请求@Overrideprotected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {/*思路: 获取到前端的提交的数据,注意 编码设置post 请求 连接数据库: 进行添加数据 添加成功: 返回部门列表页面 添加失败: 返回失败的页面 */request.setCharacterEncoding(&34;);// 获取到前端的数据,建议 name 使用复制String deptno = request.getParameter(&34;);String dname = request.getParameter(&34;);String loc = request.getParameter(&34;);// 连接数据库,添加数据Connection connection = null;PreparedStatement preparedStatement = null;// 影响数据库的行数int count = 0;try {// 1. 注册驱动,连接数据库connection = DBUtil.getConnection();// 2. 获取操作数据库对象,预编译sql语句,Sql测试String sql = &34;;preparedStatement = connection.prepareStatement(sql);// 3. 填充占位符,真正执行sql语句,// 注意: 占位符的填充是从 1 开始的,基本上数据库相关的起始下标索引都是从 1下标开始的preparedStatement.setString(1,deptno);preparedStatement.setString(2,dname);preparedStatement.setString(3,loc);// 返回影响数据库的行数count = preparedStatement.executeUpdate();// 5.释放资源} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(connection,preparedStatement,null);}// 保存成功,返回部门列表页面if (count == 1) {// 这里应该使用,重定向// 这里用的转发,是服务器内部的,不要加项目名//request.getRequestDispatcher(&34;).forward(request,response);// 重定向response.sendRedirect(request.getContextPath() + &34;);} else {// 保存失败// web当中的 html资源,这里的 &34; 表示 web 目录//request.getRequestDispatcher(&34;).forward(request,response);response.sendRedirect(request.getContextPath() + &34;);}}}
2.9 功能六:跳转到修改部门的页面 DepEditServlet
思路:获取到提交的过来的 部门编号根据部门编号修改信息,注意:部门编号是唯一的不要被修改了连接数据库,查询到相关信息显示到浏览器页面当中,方便用户修改
具体的代码编写如下
package com.RainbowSea.servlet;import com.RainbowSea.DBUtil.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 DepEditServlet extends HttpServlet {// 超链接是 doGet()请求// @Overrideprotected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {response.setContentType(&34;);PrintWriter writer = response.getWriter();writer.println(&34;);writer.println(&39;en&34;);writer.println(&34;);writer.println(&39;UTF-8&34;);writer.println(&34;);writer.println(&34;);writer.println(&34;);writer.println(&34;);writer.println(&39;&34;/dept/modify&39;post&34;);/*思路:获取到提交的过来的 部门编号根据部门编号修改信息,注意:部门编号是唯一的不要被修改了连接数据库,查询到相关信息显示到浏览器页面当中,方便用户修改 */String deptno = request.getParameter(&34;);// 连接数据库Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {// 1. 注册驱动,连接数据库connection = DBUtil.getConnection();// 2. 获取到操作数据库对象,预编译SQL语句,sql测试String sql = &34;;preparedStatement = connection.prepareStatement(sql);// 3. 填充占位符,真正执行sql语句preparedStatement.setString(1,deptno);resultSet = preparedStatement.executeQuery();// 4. 处理查询结果集while (resultSet.next()) {String dname = resultSet.getString(&34;);// 查询使用的别名,要用别名String loc = resultSet.getString(&34;);// <!-- readonly 表示只读,不可修改的作用writer.println(&39;text&39;deptno&39;&34;&34;);writer.println(&39;text&39;dname&34; + dname + &34;);writer.println(&39;text&39;loc&34; + loc + &34;);}} catch (SQLException e) {throw new RuntimeException(e);} finally {// 5.释放资源,最后使用的优先关闭(因为如果是关闭优先使用的话,再最后面使用的可能需要前面的资源,才能执行)DBUtil.close(connection,preparedStatement,resultSet);}writer.println(&39;submit&39;修改&34;);writer.println(&34;);writer.println(&34;);writer.println(&34;);}}
2.10 功能七:修改部门 DeptSaveServlet
思路:
获取到前端的提交的数据,注意 编码设置post 请求连接数据库: 进行添加数据添加成功: 返回部门列表页面添加失败: 返回失败的页面
具体的代码编写如下:
package com.RainbowSea.servlet;import com.RainbowSea.DBUtil.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.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;/** * 增加部门数据 */public class DeptSaveServlet extends HttpServlet {// 前端是注册信息,是post 请求@Overrideprotected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {/*思路: 获取到前端的提交的数据,注意 编码设置post 请求 连接数据库: 进行添加数据 添加成功: 返回部门列表页面 添加失败: 返回失败的页面 */request.setCharacterEncoding(&34;);// 获取到前端的数据,建议 name 使用复制String deptno = request.getParameter(&34;);String dname = request.getParameter(&34;);String loc = request.getParameter(&34;);// 连接数据库,添加数据Connection connection = null;PreparedStatement preparedStatement = null;// 影响数据库的行数int count = 0;try {// 1. 注册驱动,连接数据库connection = DBUtil.getConnection();// 2. 获取操作数据库对象,预编译sql语句,Sql测试String sql = &34;;preparedStatement = connection.prepareStatement(sql);// 3. 填充占位符,真正执行sql语句,// 注意: 占位符的填充是从 1 开始的,基本上数据库相关的起始下标索引都是从 1下标开始的preparedStatement.setString(1,deptno);preparedStatement.setString(2,dname);preparedStatement.setString(3,loc);// 返回影响数据库的行数count = preparedStatement.executeUpdate();// 5.释放资源} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(connection,preparedStatement,null);}// 保存成功,返回部门列表页面if (count == 1) {// 这里应该使用,重定向// 这里用的转发,是服务器内部的,不要加项目名//request.getRequestDispatcher(&34;).forward(request,response);// 重定向response.sendRedirect(request.getContextPath() + &34;);} else {// 保存失败// web当中的 html资源,这里的 &34; 表示 web 目录//request.getRequestDispatcher(&34;).forward(request,response);response.sendRedirect(request.getContextPath() + &34;);}}}
3. 最后的 web.xml 配置信息
<?xml version=&34; encoding=&34;?><web-app xmlns=&34;; xsi:schemaLocation=&34;4.0&34;/" 开始--><url-pattern>/dept/edit</url-pattern></servlet-mapping><!--修改部门信息--><servlet><servlet-name>modify</servlet-name><servlet-class>com.RainbowSea.servlet.DeptModifyServlet</servlet-class></servlet><servlet-mapping><servlet-name>modify</servlet-name><url-pattern>/dept/modify</url-pattern></servlet-mapping></web-app>
英语第三人称单数有he、she、it。第三人称单数(Third-person singular)是语言中对对话双方外其它某一个人指示时使用的代词(简称单三,亦称三单)。第三人称是相对于对话时,某一句话中,言语发出方(第一人称)和言语的。
4. 优化方案: @WebServlet 注解 + 模板方法
5. 总结:
每次前端提交的数据都通过浏览器 F12 检查的方式,查看我们提交的数据是否,是我们需要的,是否满足条件。
每次后端从前端浏览器获取到的数据,同样都是需要打印或者调试看看,我们获取的数据是否存在错误,或者乱码的情况。
如果对SQL语句不太熟练的话,建议无论是否是简单的 SQL语句都,可以先在对应的数据库中运行测试看看,是否存在错误。
尽可能的做到,每实现一点功能就测试一下,是否存在错误,而不是一顿操作下来,虽然所以代码都编写完了,但是到最后测试的时候,一堆 BUG 。
我们应该怎么去实现一个功能呢?
建议:你可以从后端往前端一步一步写。也可以从前端一步一步往后端写。都可以。但是千万要记住不要想起来什么写什么。你写代码的过程最好是程序的执行过程。也就是说:程序执行到哪里,你就写哪里。这样一个顺序流下来之后,基本上不会出现什么错误、意外。
从哪里开始?假设从前端开始,那么一定是从用户点击按钮那里开始的
分析清楚哪里使用的是 doGet 请求 ,哪里使用的是 doPost 请求。
分析清楚哪里使用的是 服务器端的转发 ,哪里使用的是 重定向机制。
注意: 在服务器当需要使用到的 jar 包,必须在 WEB-INF 的目录下,创建一个名为 lib 的目录文件夹,用来存放相关的 依赖jar 包,注意路径位置不可以修改,目录文件必须为 lib 不然,当你启动的Tocmat 服务器的时候,是无法找到该对应的 依赖jar 包的。
6. 最后: