老杜 JavaWeb 讲解(十四) ——oa项目的改造(JSP+Servlet)
(十四)JSP改造oa项目
相关视频:
使用Servlet + JSP完成oa项目的改造
-
使用Servlet处理业务,收集数据。 使用JSP展示数据。
-
将之前原型中的html文件,全部修改为jsp,然后在jsp文件头部添加page指令(指定contentType防止中文乱码),将所有的JSP直接拷贝到web目录下。
-
完成所有页面的正常流转。(页面仍然能够正常的跳转。修改超链接的请求路径。)
- <%=request.getContextPath() %> 在JSP中动态的获取应用的根路径。
-
Servlet中连接数据库,查询所有的部门,遍历结果集。
- 遍历结果集的过程中,取出部门编号、部门名、位置等信息,封装成java对象。
- 将java对象存放到List集合中。
- 将List集合存储到request域当中。
- 转发forward到jsp。
-
在JSP中:
- 从request域当中取出List集合。
- 遍历List集合,取出每个部门对象。动态生成 tr标签。
-
思考一个问题:如果我只用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文件的扩展名。
<!-- The mappings for the JSP servlet --> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping>
-
xxx.jsp文件对于小猫咪来说,只是一个普通的文本文件,web容器会将xxx.jsp文件最终生成java程序,最终调用的是java对象相关的方法,真正执行的时候,和jsp文件就没有关系了。
-
小窍门:JSP如果看不懂,建议把jsp翻译成java代码,就能看懂了。
-
-
包名bean是什么意思?
-
javabean(java的logo是一杯冒着热气的咖啡。javabean被翻译为:咖啡豆)
-
java是一杯咖啡,咖啡又是由一粒一粒的咖啡豆研磨而成。
-
整个java程序中有很多bean的存在。由很多bean组成。
-
什么是javabean?实际上javabean你可以理解为符合某种规范的java类,比如:
有无参数构造方法
属性私有化
对外提供公开的set和get方法实现java.io.Serializable接口
重写toString
重写hashCode+equals
... ...
-
javabean其实就是java中的实体类。负责数据的封装。
-
由于javabean符合javabean规范,具有更强的通用性。
-
具体代码实现:
工具类
DBUtil.java(简化数据库操作)
package com.zwm.oa.utils;
import java.sql.*;
import java.util.ResourceBundle;
/**
* @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);
}
}
}
}
Dept.java(javaBean 用来封装数据 )
package com.zwm.oa.bean;
import java.util.Objects;
/**
* @author 猪无名
* @date 2023/7/24 16 44
* discription:一个普通的java类,这个Java类可以封装零散的数据。代表一个部门。
*/
public class Dept {
private String deptno;
private String dname;
private String loc;
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;
}
public Dept(String deptno, String dname, String loc) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public Dept() {
}
@Override
public String toString() {
return "Dept{" +
"deptno='" + deptno + '\'' +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
@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
DeptServlet.java
package com.zwm.oa.web.action;
import com.zwm.oa.bean.Dept;
import com.zwm.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
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.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @author 猪无名
* @date 2023/7/23 19 02
* discription:
*/
@WebServlet({ "/dept/list","/dept/delete","/dept/detail","/dept/save","/dept/modify"})
public class DeptServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String servletPath = request.getServletPath();
if("/dept/list".equals(servletPath)){
doList(request,response);
}else if("/dept/delete".equals(servletPath)){
doDel(request,response);
}else if("/dept/detail".equals(servletPath)){
doDetail(request,response);
}else if("/dept/save".equals(servletPath)){
doSave(request,response);
}else if("/dept/modify".equals(servletPath)){
doModify(request,response);
}
}
private void doModify(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
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("更改成功");
response.sendRedirect(request.getContextPath()+"/dept/list");
} else {
System.out.println("无匹配数据");
response.sendRedirect(request.getContextPath()+"/dept/list");
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
//释放资源
DBUtil.close(conn,ps,rs);
}
}
//数据添加
private void doSave(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
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 + " 行已插入数据");
response.sendRedirect(request.getContextPath()+"/dept/list");
} else {
System.out.println("未插入任何数据");
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
//释放资源
DBUtil.close(conn,ps,rs);
}
}
//根据部门编号获取部门信息
private void doDetail(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取部门编号
String deptno = request.getParameter("deptno");
//根据部门编号获取部门信息,将部门信息封装在bean中。
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Dept dept = null;
try {
connection = DBUtil.getConnection();
String sql = "select dname,loc from dept where deptno = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, deptno);
//这个结果集中只有一条数据,不需要循环。
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
String dname = resultSet.getString("dname");
String loc = resultSet.getString("loc");
//创建豆子,封装对象。
dept = new Dept(deptno, dname, loc);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtil.close(connection, preparedStatement, resultSet);
}
request.setAttribute("dept", dept);
request.getRequestDispatcher("/"+request.getParameter("tag")+".jsp").forward(request,response);
}
//执行删除
private void doDel(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
String deptno = request.getParameter("deptno");
//System.out.println(deptno);
//连接数据库,查询所有的部门信息。
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
//获取连接
connection = DBUtil.getConnection();
String sql = "DELETE FROM dept WHERE deptno = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,deptno);
int rowsAffected = preparedStatement.executeUpdate();
if (rowsAffected > 0) {
System.out.println("删除成功");
// 删除完成后重定向回原来的页面
response.sendRedirect(request.getContextPath()+"/dept/list");
} else {
System.out.println("删除失败");
response.sendRedirect(request.getContextPath()+"/dept/list");
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBUtil.close(connection,preparedStatement, null);
}
}
/**
* 连接数据库,查询所有的部门信息,将部门信息收集好,然后跳转到JSP进行页面展示。
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
private void doList(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//连接数据库,查询所有的部门信息。
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Dept> depts = new ArrayList<>();
try {
//获取连接
connection = DBUtil.getConnection();
//执行查询语句
String sql = "select deptno,dname,loc from dept";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
// 遍历结果集
while (resultSet.next()){
String deptno = resultSet.getString("deptno");
String dname = resultSet.getString("dname");
String loc = resultSet.getString("loc");
//从一个servlet跳转到另一个jsp,就相当于从一个servlet跳转到另一个servlet。
//此时使用请求域来保存数据。
//另外,因为查询的数据比较零散,所以可以使用一个java类来封装这些数据。
Dept dept = new Dept(deptno,dname,loc);
//将部门对象放在List集合中。
depts.add(dept);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBUtil.close(connection,preparedStatement,resultSet);
}
//将一个集合放在请求域中。
request.setAttribute("deptList",depts);
//进行转发(不需要项目名)
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
JSP
list.jsp
<%@ page import="com.zwm.oa.bean.Dept" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<title>部门列表页面</title>
</head>
<body>
<script>
function del(dno){
if(window.confirm("亲,删了不可恢复哦!")){
document.location.href = "<%=request.getContextPath()%>/dept/delete?deptno=" + dno;
}
}
</script>
<h1 align="center">部门列表</h1>
<hr>
<table border="1px" align="center" width="50%">
<tr>
<th>编号</th>
<th>名称</th>
<th>位置</th>
<th>操作</th>
</tr>
<%--这里返回的是一个Object,但我们已经知道返回的是List集合,所有可以进行强制转换。--%>
<%
List<Dept> deptList = (List<Dept>)request.getAttribute("deptList");
int i = 0;
for (Dept dept : deptList) {
//System.out.println(dept);
%>
<tr>
<td><%=++i%></td>
<td><%=dept.getDeptno()%></td>
<td><%=dept.getLoc()%></td>
<td>
<a href= "#" onclick="del(<%=dept.getDeptno()%>)" >删除</a>
<a href="<%=request.getContextPath()%>/dept/detail?tag=edit&deptno=<%=dept.getDeptno()%>">修改</a>
<a href="<%=request.getContextPath()%>/dept/detail?tag=detail&deptno=<%=dept.getDeptno()%>">详情</a>
</td>
</tr>
<%
}
%>
</table>
<hr>
<a href="<%=request.getContextPath()%>/add.jsp">新增部门</a>
</body>
</html>
detail.jsp
<%@ page import="com.zwm.oa.bean.Dept" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
Dept dept = (Dept)request.getAttribute("dept");
%>
<html>
<head>
<meta charset="utf-8">
<title>部门详情</title>
</head>
<body>
<h1>部门详情</h1>
<hr>
部门编号:<%=dept.getDeptno()%> <br>
部门名称:<%=dept.getDname()%> <br>
部门位置:<%=dept.getLoc()%> <br>
<input type="button" value="后退" onclick="window.history.back()"/>
</body>
</html>
edit.jsp
<%@ page import="com.zwm.oa.bean.Dept" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
Dept dept = (Dept)request.getAttribute("dept");
%>
<html>
<head>
<meta charset="utf-8">
<title>修改部门</title>
</head>
<body>
<h1>修改部门</h1>
<hr>
<form action="<%=request.getContextPath()%>/dept/modify" method="post">
部门编号:<input type="text" name="deptno" value="<%=dept.getDeptno()%>" readonly/><br>
部门名称:<input type="text" name="deptname" value="<%=dept.getDname()%>"/><br>
部门位置:<input type="text" name="loc" value="<%=dept.getLoc()%>"/><br>
<input type="submit" value="修改"/><br>
</form>
</body>
</html>
add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<title>新增部门</title>
</head>
<body>
<h1>新增部门</h1>
<hr>
<form action="<%=request.getContextPath()%>/dept/save" method="post">
部门编号:<input type="text" name="deptno"/><br>
部门名称:<input type="text" name="deptname"/><br>
部门位置:<input type="text" name="loc"/><br>
<input type="submit" value="保存"/><br>
</form>
</body>
</html>