Servlet中的注解式开发

一、Servlet注解,简化配置

  • [x] oa项目中的web.xml文件

    • 当开发项目过大时,web.xml中需要配置的文件会非常庞大,可能会有几十兆
    • 在web.xml文件中进行Servlet信息的配置,显然开发效率较低,每一个都需要配置、
    • 而且在web.xml文件中的配置是很少需要修改的
  • [x] Servlet3.0版本之后,退出了各种Servlet基于注解式开发

    • 优点

      • 开发效率高,不需要编写大量的配置信息,直接写在Java类上使用注解进行标注
      • web.xml文件体积变小了
    • 并不是有了注解之后,web.xml文件就不需要了

      • 有的一些需要变化的信息,还是需要配置到web.xml文件中,一般都是注解+配置文件的开发模式
      • 一些不会经常变化修改的配置建议使用注解,一些可能会被修改的建议写到配置文件中

二、注解的使用

  • 第一个注解
    1. import jakarta.servlet.annotation.WebServlet;

23、Servlet中的注解式开发 - 图1

  • Servlet类上使用:@WebServlet
  • [x] Servlet注解的属性

    • name属性L:用来指定Servlet的名字,等同于<servlet-name>
    • urlPatterns属性:用来指定Servlet的映射路径,可以指定多个字符串,等同于url-pattern
    • loadOnStartUp属性:用来指定服务器在启动阶段是否加载Servlet,等同于<load-on-startup>
    • value属性

      • ⚠️如果注解的属性名是value的话,属性名可以省略@WebServlet(value = "/a")可以写为@WebServlet("/a")
  • [x] 注解对象的使用格式initPatams

    • @注解名称(属性名=属性值,属性名=属性值,属性名=属性值)

23、Servlet中的注解式开发 - 图2

  • 不需要将所有的属性都写上,只需要提供需要的(需要什么用什么)

⚠️当注解的属性是一个数组,并且数字中只有一个元素,大括号可以省略

三、模板方法设计模式解决类爆炸

  • 如果一个复杂的业务系统,类太多,会导致类爆炸(类的数量急剧增多)
  • 可以使用模板设计模式解决类爆炸

❓如何解决类爆炸问题

  • 一个请求对应一个方法
  • 一个业务对应一个Servlet类
  • 处理部门的业务的对应一个DeptServlet
  • 处理用户相关的业务对应一个UserServlet
  • 处理银行卡片业务的对应一个CardServlet
  • 通配写法

23、Servlet中的注解式开发 - 图3

  1. package oa.action;
  2. import jakarta.servlet.ServletException;
  3. import jakarta.servlet.annotation.WebServlet;
  4. import jakarta.servlet.http.HttpServlet;
  5. import jakarta.servlet.http.HttpServletRequest;
  6. import jakarta.servlet.http.HttpServletResponse;
  7. import oa.untils.DBUtil;
  8. import java.io.IOException;
  9. import java.io.PrintWriter;
  10. import java.sql.Connection;
  11. import java.sql.PreparedStatement;
  12. import java.sql.ResultSet;
  13. import java.sql.SQLException;
  14. /**
  15. * @Author: 小雷学长
  16. * @Date: 2022/3/23 - 21:31
  17. * @Version: 1.8
  18. */
  19. //模板类
  20. @WebServlet({"/dept/list", "/dept/save", "/dept/edit", "/dept/detail", "/dept/delete", "/dept/update"})
  21. //通配写法
  22. //只要是路径已"/dept"开始的,都走Servlet
  23. //@WebServlet("/dept/*")
  24. public class DeptServlet extends HttpServlet {
  25. //模板方法
  26. //重写Servlet方法(并没有重写doGet或者doPost
  27. @Override
  28. protected void service(HttpServletRequest request, HttpServletResponse response)
  29. throws ServletException, IOException {
  30. //获取ServletPath
  31. String servletPath = request.getServletPath();
  32. if ("/dept/list".equals(servletPath)) {
  33. doList(request, response);
  34. } else if ("/dept/save".equals(servletPath)) {
  35. doSave(request, response);
  36. } else if ("/dept/edit".equals(servletPath)) {
  37. doEdit(request, response);
  38. } else if ("/dept/detail".equals(servletPath)) {
  39. doDeail(request, response);
  40. } else if ("/dept/delete".equals(servletPath)) {
  41. doDelete(request, response);
  42. } else if ("/dept/update".equals(servletPath)) {
  43. doUpdate(request, response);
  44. }
  45. }
  46. private void doList(HttpServletRequest request, HttpServletResponse response)
  47. throws ServletException, IOException {
  48. {
  49. //获取应用的根路径
  50. String contextPath = request.getContextPath();
  51. //设置响应的内容类型
  52. response.setContentType("text/html");
  53. PrintWriter out = response.getWriter();
  54. out.print(" <!DOCTYPE html>");
  55. out.print("<html lang='en'>");
  56. out.print("<head>");
  57. out.print(" <meta charset='UTF-8'>");
  58. out.print(" <title>部门列表</title>");
  59. out.print("</head>");
  60. out.print("<body>");
  61. out.print("<script type='text/javascript'>");
  62. out.print(" function del(dno) {");
  63. out.print(" if(window.confirm('亲,删了不可恢复哦!')){");
  64. out.print(" document.location.href = '" + contextPath + "/dept/delete?deptno=' + dno");
  65. out.print(" }");
  66. out.print("}");
  67. out.print("</script>");
  68. out.print("<h1 align='center'>部门列表</h1>");
  69. out.print("<hr>");
  70. out.print("<table border='1px' align='center' width='50%'>");
  71. out.print(" <tr>");
  72. out.print(" <th>序号</th>");
  73. out.print(" <th>部门编号</th>");
  74. out.print(" <th>部门名称</th>");
  75. out.print(" <th>操作</th>");
  76. out.print(" </tr>");
  77. out.print(" <!--以上是固定的-->");
  78. /*
  79. 上面一部分是死的
  80. */
  81. /*
  82. * 连接数据库
  83. */
  84. Connection conn = null;
  85. PreparedStatement ps = null;
  86. ResultSet rs = null;
  87. try {
  88. //获取连接
  89. conn = DBUtil.getConnection();
  90. //获取预编译的数据库操作对象
  91. String sql = "select deptno,dname ,loc from dept";
  92. ps = conn.prepareStatement(sql);
  93. //执行SQL语句
  94. rs = ps.executeQuery();
  95. //处理结果集
  96. int i = 0;
  97. while (rs.next()) {
  98. String deptno = rs.getString("deptno");
  99. String dname = rs.getString("dname");
  100. String loc = rs.getString("loc");
  101. out.print(" <tr>");
  102. out.print(" <td>" + (++i) + "</td>");
  103. out.print(" <td>" + deptno + "</td>");
  104. out.print(" <td>" + dname + "</td>");
  105. out.print(" <td>");
  106. out.print("<a href='javascript:void(0)' onclick='del(" + deptno + ")'>删除</a>");
  107. out.print(" <a href='/oa/dept/edit?deptno=" + deptno + "'>修改</a>");
  108. out.print(" <a href='" + contextPath + "/dept/detail?deptno=" + deptno + "'>详情</a>");
  109. out.print(" </td>");
  110. out.print(" </tr>");
  111. }
  112. } catch (SQLException e) {
  113. e.printStackTrace();
  114. } finally {
  115. //释放资源
  116. DBUtil.close(conn, ps, rs);
  117. }
  118. /*
  119. 下面一部分是死的
  120. */
  121. out.print(" <!--一下是固定的-->");
  122. out.print("</table>");
  123. out.print("<hr>");
  124. out.print("<a href='" + contextPath + "/add.html'>新增部门</a>");
  125. out.print("</body>");
  126. out.print("</html>");
  127. }
  128. }
  129. private void doSave(HttpServletRequest request, HttpServletResponse response)
  130. throws ServletException, IOException {
  131. {
  132. //获取部门信息
  133. String deptno = request.getParameter("deptno");
  134. String dname = request.getParameter("dname");
  135. String loc = request.getParameter("loc");
  136. //连接数据库执行insert语句
  137. Connection conn = null;
  138. PreparedStatement ps = null;
  139. int count = 0;
  140. try {
  141. conn = DBUtil.getConnection();
  142. String sql = "insert into dept(deptno,dname,loc) values(?,?,?)";
  143. ps = conn.prepareStatement(sql);
  144. ps.setString(1, deptno);
  145. ps.setString(2, dname);
  146. ps.setString(3, loc);
  147. count = ps.executeUpdate();
  148. } catch (SQLException e) {
  149. e.printStackTrace();
  150. } finally {
  151. DBUtil.close(conn, ps, null);
  152. }
  153. //判断新增成功还是失败
  154. if (count == 1) {
  155. //新增成功
  156. //仍然跳回到部门列表页面
  157. //部门列表页面需要执行另一个Servlet,利用转发机制
  158. //转发一次请求
  159. // request.getRequestDispatcher("/dept/list").forward(request, response);
  160. //建议使用重定向,因为重定向是一次全新的请求,不会受dopost、doget方法影响
  161. response.sendRedirect(request.getContextPath() + "/dept/list");
  162. } else {
  163. //新增失败
  164. // request.getRequestDispatcher("/error.html").forward(request, response);
  165. //建议使用重定向,因为重定向是一次全新的请求,不会受dopost、doget方法影响
  166. response.sendRedirect(request.getContextPath() + "/error.hmtl");
  167. }
  168. }
  169. }
  170. private void doEdit(HttpServletRequest request, HttpServletResponse response)
  171. throws ServletException, IOException {
  172. {
  173. response.setContentType("text/html");
  174. PrintWriter out = response.getWriter();
  175. String contextPath = request.getContextPath();
  176. out.print("<html lang='en'>");
  177. out.print("<head>");
  178. out.print(" <meta charset='UTF-8'>");
  179. out.print(" <title>修改部门</title>");
  180. out.print("</head>");
  181. out.print("<body>");
  182. out.print("<h1>修改部门</h1>");
  183. out.print("<hr>");
  184. out.print("<form action='" + contextPath + "/dept/update' method='post'>");
  185. //获取部门编号
  186. String deptno = request.getParameter("deptno");
  187. //连接数据库执行insert语句
  188. Connection conn = null;
  189. PreparedStatement ps = null;
  190. ResultSet rs = null;
  191. try {
  192. conn = DBUtil.getConnection();
  193. String sql = "select dname,loc from dept where deptno=?";
  194. ps = conn.prepareStatement(sql);
  195. ps.setString(1, deptno);
  196. rs = ps.executeQuery();
  197. if (rs.next()) {
  198. String dname = rs.getString("dname");
  199. String loc = rs.getString("loc");
  200. //输出动态网页
  201. out.print(" 部门编号<input type='text' name='deptno' value='" + deptno + "' readonly><br><!--readonly只读-->");
  202. out.print(" 部门名称<input type='text' name='dname' value='" + dname + "'><br>");
  203. out.print(" 部门位置<input type='text' name='loc' value='" + loc + "'><br>");
  204. }
  205. } catch (SQLException e) {
  206. e.printStackTrace();
  207. } finally {
  208. DBUtil.close(conn, ps, rs);
  209. }
  210. //判断新增成功还是失败
  211. out.print(" <input type='submit' value='修改'><br>");
  212. out.print("");
  213. out.print("</form>");
  214. out.print("");
  215. out.print("</body>");
  216. out.print("</html>");
  217. }
  218. }
  219. private void doDeail(HttpServletRequest request, HttpServletResponse response)
  220. throws ServletException, IOException {
  221. {
  222. response.setContentType("text/html");
  223. PrintWriter out = response.getWriter();
  224. out.print("<!DOCTYPE html>");
  225. out.print("<html lang='en'>");
  226. out.print("<head>");
  227. out.print(" <meta charset='UTF-8'>");
  228. out.print(" <title>部门详情</title>");
  229. out.print("</head>");
  230. out.print("<body>");
  231. out.print("<h1>部门详情</h1>");
  232. out.print("<hr>");
  233. //获取部门编号
  234. //虽然提交的是30,但服务器获取的是30这个字符串
  235. String deptno = request.getParameter("deptno");
  236. /*
  237. * 连接数据库
  238. */
  239. Connection conn = null;
  240. PreparedStatement ps = null;
  241. ResultSet rs = null;
  242. try {
  243. //获取连接
  244. conn = DBUtil.getConnection();
  245. //获取预编译的数据库操作对象
  246. String sql = "select deptno,dname,loc from dept where deptno=?";
  247. ps = conn.prepareStatement(sql);
  248. ps.setString(1, deptno);
  249. //这个结果集一定只有一个元素
  250. //执行SQL语句
  251. rs = ps.executeQuery();
  252. //处理结果集
  253. if (rs.next()) {
  254. String dname = rs.getString("dname");
  255. String loc = rs.getString("loc");
  256. out.print("部门编号" + deptno + "<br>");
  257. out.print("部门名称" + dname + "<br>");
  258. out.print("部门位置" + loc + "<br>");
  259. }
  260. } catch (SQLException e) {
  261. e.printStackTrace();
  262. } finally {
  263. //释放资源
  264. DBUtil.close(conn, ps, rs);
  265. }
  266. out.print("");
  267. out.print("<form action='list.html'>");
  268. out.print(" <input type='button' value='后退' onclick='window.history.back()'>");
  269. out.print("");
  270. out.print("</form>");
  271. out.print("");
  272. out.print("</body>");
  273. out.print("</html>");
  274. }
  275. }
  276. public void doDelete(HttpServletRequest request, HttpServletResponse response)
  277. throws ServletException, IOException {
  278. {
  279. //根据部门编号,删除部门
  280. //获取部门编号
  281. String deptno = request.getParameter("deptno");
  282. //连接数据库删除数据
  283. Connection conn = null;
  284. PreparedStatement ps = null;
  285. int count = 0;
  286. try {
  287. conn = DBUtil.getConnection();
  288. //开启事务(自动提交机制关闭)(非必要)
  289. // conn.setAutoCommit(false);
  290. String sql = "delete from dept where deptno=?";
  291. ps = conn.prepareStatement(sql);
  292. ps.setString(1, deptno);
  293. //返回值是:影响了数据库表当中多少条记录
  294. count = ps.executeUpdate();
  295. //事务提交(非必要)
  296. // conn.commit();
  297. } catch (SQLException e) {
  298. e.printStackTrace();
  299. } finally {
  300. DBUtil.close(conn, ps, null);
  301. }
  302. //判断删除成功还是失败
  303. if (count == 1) {
  304. //删除成功
  305. //仍然跳回到部门列表页面
  306. //部门列表页面需要执行另一个Servlet,利用转发机制
  307. //request.getRequestDispatcher("/dept/list").forward(request, response);
  308. //建议使用重定向,因为重定向是一次全新的请求,不会受dopost、doget方法影响
  309. response.sendRedirect(request.getContextPath() + "/dept/list");
  310. } else {
  311. //删除失败
  312. //建议使用重定向,因为重定向是一次全新的请求,不会受dopost、doget方法影响
  313. response.sendRedirect(request.getContextPath() + "/error.html");
  314. }
  315. }
  316. }
  317. private void doUpdate(HttpServletRequest request, HttpServletResponse response)
  318. throws ServletException, IOException {
  319. {
  320. response.setContentType("text/html");
  321. PrintWriter out = response.getWriter();
  322. String deptno = request.getParameter("deptno");
  323. String dname = request.getParameter("dname");
  324. String loc = request.getParameter("loc");
  325. //连接数据库执行insert语句
  326. Connection conn = null;
  327. PreparedStatement ps = null;
  328. ResultSet rs = null;
  329. int count = 0;
  330. try {
  331. conn = DBUtil.getConnection();
  332. String sql = "update dept set dname = ?,loc = ? where deptno = ?";
  333. ps = conn.prepareStatement(sql);
  334. ps.setString(1, dname);
  335. ps.setString(2, loc);
  336. ps.setString(3, deptno);
  337. count = ps.executeUpdate();
  338. } catch (SQLException e) {
  339. e.printStackTrace();
  340. } finally {
  341. DBUtil.close(conn, ps, rs);
  342. }
  343. if (count == 1) {
  344. //更新成功
  345. //跳转到部门列表页面,转发机制
  346. // request.getRequestDispatcher("/dept/list").forward(request,response);
  347. //建议使用重定向,因为重定向是一次全新的请求,不会受dopost、doget方法影响
  348. response.sendRedirect(request.getContextPath() + "/dept/list");
  349. } else {
  350. //更新失败
  351. // request.getRequestDispatcher("/error.html").forward(request,response);
  352. //建议使用重定向,因为重定向是一次全新的请求,不会受dopost、doget方法影响
  353. response.sendRedirect(request.getContextPath() + "/error.html");
  354. }
  355. }
  356. }
  357. }