JSP | 基于Servlet和JSP改造oa项目
目录
一: 基于Servlet和JSP改造oa项目
第一步:将原型中的.html文件,全部修改为.jsp文件
第二步:连接数据库,完成对应的操作
(1)index.jsp 跳转到 list.jsp
(2)list.jsp 跳转到detail.jsp
(3)list.jsp 跳转到 删除操作
(4)list.jsp 跳转到 add.jsp
(5)list.jsp 跳转到 modify.jsp
一: 基于Servlet和JSP改造oa项目
使用Servlet处理业务,收集数据; 使用JSP展示数据!
第一步:将原型中的.html文件,全部修改为.jsp文件
(1)将之前原型模板中的".html"文件,全部修改为".jsp",然后在所有的".jsp"文件头部添加page指令(指定contentType防止中文乱码),将所有的JSP直接拷贝到web目录下。
补充:ctrl+shift+del清除浏览器的缓存!
(2)完成所有页面的正常流转。(页面仍然能够正常的跳转,修改超链接的请求路径)
①这里就需要把所有的超连接路径更改,改成.jsp文件的格式;并加上项目名!
②这里就能体现出.jsp的优势,在jsp中是可以写java代码的;对于前端中的项目名,就可以通过java代码获取,不需要写死了!
③例如:对于欢迎页面index.jsp
在JSP中动态的获取应用的根路径<a href="/list.jsp">查看部门列表
(3)目前所有原型页面如下:都是静态的页面,都是直接跳转到jsp展示数据,中间没有经过servlet获取数据!
①index.jsp 可以跳转到 list.jsp
欢迎使用OA系统 <a href="/list.jsp">查看部门列表
②以list.jsp为展开对象,可以跳转到:detail.jsp、modify.jsp、add.jsp
部门列表页面 function del(dno){// 弹出确认框,用户点击确定,返回true,点击取消返回falsevar ok = window.confirm("亲,删了不可恢复哦!");if(ok){document.location.href = "/dept/delete?deptno=" + dno;}}部门列表
序号 部门编号 部门名称 操作 1 10 销售部 删除<a href="/modify.jsp">修改<a href="/detail.jsp">详情
<a href="/add.jsp">新增部门
③detail.jsp展示完以后在跳转到list.jsp
部门详情 部门详情
部门编号:20
部门名称:销售部
部门位置:北京
④modify.jsp展示完以后在跳转到list.jsp
修改部门 修改部门
<form action="/list.jsp" method="get">部门编号
部门名称
部门位置
⑤add.jsp展示完以后在跳转到list.jsp
新增部门 新增部门
<form action="/list.jsp" method="get">部门编号
部门名称
部门位置
第二步:连接数据库,完成对应的操作
前面我们已经完成了jsp做数据展示的操作,但是并没有进行连接数据库;所以要先跳转到servlet完成数据的收集操作,然后通过servlet再跳到jsp做数据展示的操作!
(1)index.jsp 跳转到 list.jsp
(1)先对index.jsp模板原型进行修改;把超链接路径修改为跳转到一个servlet
<a href="/list.jsp">查看部门列表<a href="/dept/list">查看部门列表
(2)通过注解式开发,连接数据库,取出数据!(要有封装对象的意识---面向抽象编程)
此时取出的数据实际上是很零散的,所以不妨封装一个Dept对象,把取出来的数据封装到这个对象里面。同时在创建一个ArrayList集合depts,把所有的对象在放到这个集合里。然后在通过请求域调用setAttribute方法,把这个集合放到请求域当中。最后在调用getRequestDispatcher方法,通过转发的方式调转到另一个jsp进行数据的展示
①封装的Dept对象用来存放取出来的零散数据
package com.bjpowernode.oa.bean;import java.util.Objects;/** * 普通的java类,张个java类可以封装零散的数据 * @Author:朗朗乾坤 * @Package:com.bjpowernode.oa.bean * @Project:JavaWeb * @name:Dept * @Date:2022/11/28 10:59 */public class Dept { private String deptno; private String dname; private String loc; // 构造方法 public Dept() { } public Dept(String deptno, String dname, String loc) { this.deptno = deptno; this.dname = dname; this.loc = loc; } // setter and getter 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; } // 重写toString方法 @Override public String toString() { return "Dept{" + "deptno='" + deptno + '\'' + ", dname='" + dname + '\'' + ", loc='" + loc + '\'' + '}'; } // 重写equals方法 和 hashCode方法 @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); }}
②跳转到的servlet进行数据的收集
package com.bjpowernode.oa.web.action;import com.bjpowernode.oa.bean.Dept;import com.bjpowernode.oa.utils.DBUtil;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.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;/** * @Author:朗朗乾坤 * @Package:com.bjpowernode.oa.web.action * @Project:JavaWeb * @name:DeptServlet * @Date:2022/11/28 10:39 */@WebServlet({"/dept/list"})public class DeptServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取servlet path String servletPath = request.getServletPath(); if ("/dept/list".equals(servletPath)){ doList(request,response); } } /** *1、 连接数据库,查询所有的部门信息,然后跳转到jsp做页面展示 * @param request * @param response * @throws ServletException * @throws IOException */ private void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ // 再创建一个容器,用来存储部门 ArrayList depts = new ArrayList(); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // 连接数据库 conn = DBUtil.getCoonetion(); // 获取预编译的数据库操作对象 String sql = "select deptno,dname,loc from dept"; ps = conn.prepareStatement(sql); // 执行sql rs = ps.executeQuery(); // 遍历查询结果集 while (rs.next()) { // 取出数据 String deptno = rs.getString("deptno"); String dname = rs.getString("dname"); String loc = rs.getString("loc"); // 将零散的数据封装一个对象放进去 Dept dept = new Dept(); dept.setDeptno(deptno); dept.setDname(dname); dept.setLoc(loc); // 肯定不止一个对象,所以创建一个集合(容器),用来存储部门对象 depts.add(dept); } } catch (SQLException e) { e.printStackTrace(); }finally { DBUtil.close(conn,ps,rs); } // 将集合放到请求域当中 request.setAttribute("deptList",depts); // 转发(不要重定向) request.getRequestDispatcher("/list.jsp").forward(request,response); }}
③通过转发的方式跳转到的另一个list.jsp,进行数据的展示
重点:对于for循环打印,这里实际上是拆分开了,但是转化为java代码还是一个完整的for循环;第一次见到这种输出方式,可能会比较不适应!
部门列表页面 function del(dno){// 弹出确认框,用户点击确定,返回true,点击取消返回falsevar ok = window.confirm("亲,删了不可恢复哦!");if(ok){document.location.href = "/dept/delete?deptno=" + dno;}}部门列表
序号 部门编号 部门名称 操作 <%// 从request域当中取出集合// getAttribute取出来的是Object类型,这里进行了强制类型转换List deptList = (List)request.getAttribute("deptList");// 循环遍历int i =0;for(Dept dept:deptList){%>删除<a href="/modify.jsp">修改<a href="/detail.jsp">详情
<a href="/add.jsp">新增部门
④思考:如果只使用JSP这一个技术,能不能开发web应用?
①当然可以使用JSP来完成所有的功能。因为JSP就是Servlet,在JSP的里面写的代码就是在service方法当中的,所以在当中完全可以编写JDBC代码,连接数据库,查询数据,也可以在这个方法当中编写业务逻辑代码,处理业务都是可以的,所以使用单独的JSP开发web应用完全没问题。
②虽然JSP一个技术就可以完成web应用,但是不建议,还是建议采用servlet + jsp的方式进行开发;这样都能将各自的优点发挥出来。JSP就是做数据展示!Servlet就是做数据的收集!(JSP中编写的Java代码越少越好)一定要职责分明!
⑤思考:JSP文件的扩展名必须是xxx.jsp吗?
①jsp文件的扩展名是可以配置的,不是固定的。
②在CATALINA_HOME/conf/web.xml,在这个文件当中配置jsp文件的扩展名。
③xxx.jsp文件对于Tomcat来说,只是一个普通的文本文件,web容器会将xxx.jsp文件最终生成java程序,最终调用的是java对象相关的方法,真正执行的时候,和jsp文件没有关系。
④小窍门:如果JSP代码看不懂,建议把jsp翻译成java代码,就能看懂了!
jsp *.jsp *.jspx
(2)list.jsp 跳转到detail.jsp
①对list.jsp中的详情超链接路径进行更改;并把部门编号也传过去
<a href="/detail.jsp">详情<a href="/dept/detail?deptno=">详情
②跳转到servlet,根据deptno进行数据的收集
这里就和上面不同,上面我们是查询所有的数据,有很多组,需要先把数据放到对象里,再把对象放到集合里;而这里每次使根据depto编号进行查询,就一组数据,所以不需要集合!
/** *2、 根据部门编号,获取部门的详细信息 * @param request * @param response * @throws ServletException * @throws IOException */ private void doDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ // 创建一个集合,用来存放数据 Dept dept = new Dept(); // 通过key获取value,获取部门标号 String deptno = request.getParameter("deptno"); // 根据部门编号获取部门信息,将部门信息封装成对象 // 不需要集合,因为只有一个对象的数据 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // 获取连接 conn = DBUtil.getCoonetion(); // 获取预编译的数据库操作对象 String sql = "select 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"); // 把数据封装成一个对象 // Dept dept = new Dept(); 定义到这里,下面转发使用不了 dept.setDeptno(deptno); dept.setDname(dname); dept.setLoc(loc); } } catch (SQLException e) { e.printStackTrace(); }finally { DBUtil.close(conn,ps,rs); } // 将封装的对象放到请求域当中 request.setAttribute("deptList",dept); // 转发(不要重定向) request.getRequestDispatcher("/detail.jsp").forward(request,response); }
③通过转发的方式跳转到的另一个detail.jsp,进行数据的展示
部门详情 部门详情
部门编号:
部门名称:
部门位置:
(3)list.jsp 跳转到 删除操作
①对list.jsp中的删除超链接路径进行更改;这里是使用一个回调函数进行路径的跳转
删除// 修改为<a href="javascript:void(0)" onclick="del()">删除// 回调函数如下,没有修改: function del(dno) { // 弹出确认框,用户点击确定,返回true,点击取消返回false var ok = window.confirm("亲,删了不可恢复哦!"); if (ok) { document.location.href = "/dept/delete?deptno=" + dno; } }
②跳转到servlet,根据deptno进行数据的收集;并且再次跳转到/dept/list页面进行数据的展示,这里使用的是重定向,因为不涉及从域中存取数据,所以尽可能使用重定向!
/** *3、 根据部门编号,删除部门 * @param request * @param response * @throws ServletException * @throws IOException */ 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.getCoonetion(); 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) { // 删除成功,重定向到list页面;因为这里没有想域中放入数据,所以使用重定向 // 重定向是要加项目名的,动态获取 String contextPath = request.getContextPath(); response.sendRedirect(contextPath+"/dept/list"); } }
(4)list.jsp 跳转到 add.jsp
①对list.jsp中的详新增超链接路径不要更改,因为需要一个提交的表单;从add.jsp这个表单中跳转到servlet
注:这里是提交数据,所以应该使用post请求!
<a href="/add.jsp">新增部门<form action="/list.jsp" method="get"><form action="/dept/add" method="post">
②add.jsp
新增部门 新增部门
<%--<form action="/list.jsp" method="get">--%><form action="/dept/add" method="post">部门编号
部门名称
部门位置
③跳转到servlet,根据前端提交的数据,调用getParameter方法获取到后,进行数据的插入;然后再通过重定向/dept/list页面,进行数据的展示
/** * 4、根据前端提交的数据,新增部门 * @param request * @param response * @throws ServletException * @throws IOException */ private void doAdd(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.getCoonetion(); 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) { response.sendRedirect(request.getContextPath() + "/dept/list"); } }
(5)list.jsp 跳转到 modify.jsp
思考:我们已经知道对于修改实际上有两次连接数据库的操作;第一次点击list页面的修改实际上就相当于查询;所以我们不妨就让 修改和详情 共享一个页面;然后在打一个标记;根据标记决定最终是跳转到detail.jsp还是modify.jsp
①修改list.jsp代码;两个走的是通过一个servlet(/dept/detail),有一个标记f
<a href="/dept/detail?f=modify&deptno=">修改<a href="/dept/detail?f=detail&deptno=">详情
②修改/dept/detail代码,就需要获取标记f,根据标记f来决定跳转的页面
// 方法1:获取这个标记,然后讨论String f = request.getParameter("f");if ("modify".equals(f)){ request.getRequestDispatcher("/modify.jsp").forward(request,response);}else if ("detail".equals(f)){ request.getRequestDispatcher("/detail.jsp").forward(request,response);}// 方法2:进行拼串String forward = "/"+request.getParameter("f")+".jsp";request.getRequestDispatcher(forward).forward(request,response);
③对modify.jsp进行修改,也要修改成post请求
修改部门 修改部门
<!--<form action="/list.jsp" method="get">部门编号
部门名称
部门位置
--><form action="/dept/modify" method="post">部门编号<input type="text" name="deptno" value="" readonly />
部门名称<input type="text" name="dname" value=""/>
部门位置<input type="text" name="loc" value=""/>
④跳转到/dept/modify,进行数据的更改
/** * 5、根据部门名称,进行修改 * @param request * @param response * @throws ServletException * @throws IOException */ 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.getCoonetion(); 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"); } }