目录
一: 基于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展示数据!
(1)将之前原型模板中的".html"文件,全部修改为".jsp",然后在所有的".jsp"文件头部添加page指令(指定contentType防止中文乱码),将所有的JSP直接拷贝到web目录下。
补充:ctrl+shift+del清除浏览器的缓存!
<%@page contentType="text/html;charset=UTF-8"%>
(2)完成所有页面的正常流转。(页面仍然能够正常的跳转,修改超链接的请求路径)
①这里就需要把所有的超连接路径更改,改成.jsp文件的格式;并加上项目名!
②这里就能体现出.jsp的优势,在jsp中是可以写java代码的;对于前端中的项目名,就可以通过java代码获取,不需要写死了!
③例如:对于欢迎页面index.jsp
<%=request.getContextPath()%> 在JSP中动态的获取应用的根路径
/list.jsp">查看部门列表
(3)目前所有原型页面如下:都是静态的页面,都是直接跳转到jsp展示数据,中间没有经过servlet获取数据!
①index.jsp 可以跳转到 list.jsp
<%@page contentType="text/html;charset=UTF-8"%>
欢迎使用OA系统 /list.jsp">查看部门列表
②以list.jsp为展开对象,可以跳转到:detail.jsp、modify.jsp、add.jsp
<%@page contentType="text/html;charset=UTF-8"%>
部门列表页面 部门列表
序号 部门编号 部门名称 操作 1 10 销售部 删除/modify.jsp">修改/detail.jsp">详情
/add.jsp">新增部门
③detail.jsp展示完以后在跳转到list.jsp
<%@page contentType="text/html;charset=UTF-8" %>
部门详情 部门详情
部门编号:20
部门名称:销售部
部门位置:北京
④modify.jsp展示完以后在跳转到list.jsp
<%@page contentType="text/html;charset=UTF-8"%>
修改部门 修改部门
⑤add.jsp展示完以后在跳转到list.jsp
<%@page contentType="text/html;charset=UTF-8"%>
新增部门 新增部门
前面我们已经完成了jsp做数据展示的操作,但是并没有进行连接数据库;所以要先跳转到servlet完成数据的收集操作,然后通过servlet再跳到jsp做数据展示的操作!
(1)先对index.jsp模板原型进行修改;把超链接路径修改为跳转到一个servlet
/list.jsp">查看部门列表
/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 getterpublic 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方法@Overridepublic String toString() {return "Dept{" +"deptno='" + deptno + '\'' +", dname='" + dname + '\'' +", loc='" + loc + '\'' +'}';}// 重写equals方法 和 hashCode方法@Overridepublic 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);}@Overridepublic 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 {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取servlet pathString 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);// 执行sqlrs = 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循环;第一次见到这种输出方式,可能会比较不适应!
<%@ page import="com.bjpowernode.oa.bean.Dept" %>
<%@ page import="java.util.List" %><%@page contentType="text/html;charset=UTF-8"%>
部门列表页面 部门列表
序号 部门编号 部门名称 操作 <%// 从request域当中取出集合// getAttribute取出来的是Object类型,这里进行了强制类型转换List deptList = (List)request.getAttribute("deptList");// 循环遍历int i =0;for(Dept dept:deptList){%><%=++i%> <%=dept.getDeptno()%> <%=dept.getLoc()%> 删除/modify.jsp">修改/detail.jsp">详情 <%}%>
/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
①对list.jsp中的详情超链接路径进行更改;并把部门编号也传过去
/detail.jsp">详情
/dept/detail?deptno=<%=dept.getDeptno()%>">详情
②跳转到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);// 执行sqlrs = 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,进行数据的展示
<%@ page import="com.bjpowernode.oa.bean.Dept" %>
<%@page contentType="text/html;charset=UTF-8" %>
部门详情 部门详情
<%// 从request域当中取出数据,强制类型转换Dept dept = (Dept)request.getAttribute("deptList");%>部门编号:<%=dept.getDeptno()%>
部门名称:<%=dept.getDname()%>
部门位置:<%=dept.getLoc()%>
①对list.jsp中的删除超链接路径进行更改;这里是使用一个回调函数进行路径的跳转
删除
// 修改为
)">删除// 回调函数如下,没有修改:
②跳转到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");}}
①对list.jsp中的详新增超链接路径不要更改,因为需要一个提交的表单;从add.jsp这个表单中跳转到servlet
注:这里是提交数据,所以应该使用post请求!
/add.jsp">新增部门
②add.jsp
<%@page contentType="text/html;charset=UTF-8"%>
新增部门 新增部门
<%--
③跳转到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");}}
思考:我们已经知道对于修改实际上有两次连接数据库的操作;第一次点击list页面的修改实际上就相当于查询;所以我们不妨就让 修改和详情 共享一个页面;然后在打一个标记;根据标记决定最终是跳转到detail.jsp还是modify.jsp
①修改list.jsp代码;两个走的是通过一个servlet(/dept/detail),有一个标记f
/dept/detail?f=modify&deptno=<%=dept.getDeptno()%>">修改
/dept/detail?f=detail&deptno=<%=dept.getDeptno()%>">详情
②修改/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请求
<%@ page import="com.bjpowernode.oa.bean.Dept" %>
<%@page contentType="text/html;charset=UTF-8"%>
修改部门 修改部门
<%Dept dept = (Dept)request.getAttribute("dept");%>
④跳转到/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");}}