我们每写一步,就测试一步,不要等到所有都写好了再测试,如果都写好了再测试,最后出错的话,会很崩溃,代码量大,调试就不容易,话不多说,开始今天的练手项目。下面的代码,每一步都是按照我自己的步骤,一步一步敲出来,调试出来的,大家第一遍可以跟着敲代码,理解其中的思想,后面自己再根据逻辑敲一遍,敲代码过程中,我所遇到的问题,在文中也会一一说明。
在文章最后给出本次练手项目的源码。
Servlet负责写Java程序,JSP负责展示页面
首先我们先写几个页面,在没有Java程序的时候,把流程跑通,然后再根据每个功能来写Java程序,思路一定要清晰,在写代码之前,要先想好每一步要干什么。
准备的页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页面title>
head>
<body>
<a href="list.jsp">欢迎使用oa系统a>
body>
html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<%--新增数据以后,我们点击保存后要回到列表页面--%>
<h1>新增页面h1>
<form action="list.jsp" method="post">
部门编号:<input type="text" name="deptnum" ><br>
部门名称:<input type="text" name="deptname" ><br>
部门位置:<input type="text" name="loc"><br>
<input type="submit" value="保存">
form>
body>
html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h1>修改页面h1>
<%--修改页面应该是先返回对应的信息,然后我们点击修改,就可以修改里面的数据--%>
<form action="list.jsp" method="post">
部门编号:<input type="text" value="10"><br>
部门名称:<input type="text" value="研发部"><br>
部门位置:<input type="text" value="杭州"><br>
<input type="submit" value="修改">
form>
body>
html>
%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h1>详情页面h1>
<%--我们可以看到部门的具体信息,点击后退就回到列表页面--%>
部门编号:<input type="text" value="10"><br>
部门名称:<input type="text" value="研发部"><br>
部门位置:<input type="text" value="杭州"><br>
<input type="button" value="后退" onclick="window.history.back()"/>
body>
html>
我们写程序可以从前端往后端写,也可以由后端往前端写,大家选择一个方向来,我这里以前端往后端来演示。
@WebServlet("/dept/list")
public class DeptServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//模板方法设计模式
/**
* 我们可以获取servlet的路径,根据路径来执行相应的方法
*/
String servletPath = request.getServletPath();
if ("/dept/list".equals(servletPath)){
doList(request,response);
}
}
private void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 使用JDBC连接数据库,查询表中数据
*/
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
List<User> list=new ArrayList<>();
try {
conn= DBUtils.getConnection();
String sql="select deptno,dname,loc from dept";
ps=conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()){
String deptno = rs.getString("deptno");
String dname = rs.getString("dname");
String loc = rs.getString("loc");
User user=new User(deptno,dname,loc);
list.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.close(conn,ps,rs);
}
//转发给jsp进行页面展示
request.setAttribute("list",list);
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
list.jsp—部门列表页面
因为第一次是为了跑通页面,里面的数据都是写死的,现在要从数据库查出数据,所以要写Java代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<%--展示部门列表页面,里面有各种数据,点击各种操作就可以进行相应操作--%>
<h1 align="center">部门列表页面h1>
<table align="center" border="1px" width="50%">
<tr>
<th>序号th>
<th>部门编号th>
<th>部门名称th>
<th>部门位置th>
<th>操作th>
tr>
<%
List<User> list = (List<User>) request.getAttribute("list");
int cnt=0;
%>
<%
for(User user:list){
String deptno = user.getDeptno();
String dname = user.getDname();
String loc = user.getLoc();
%>
<tr>
<th><%=++cnt%>th>
<th><%=deptno%>th>
<th><%=dname%>th>
<th><%=loc%>th>
<th>
<a href="detail.jsp">详情a>
<a href="edit.jsp">修改a>
<a href="modify.jsp">删除a>
<a href="add.jsp">新增a>
th>
tr>
<%
}
%>
table>
body>
html>
程序要注意的地方:
欢迎页面的超链接路径记得改成我们要执行的Servlet的映射路径
/dept/list>欢迎使用oa系统
接下来看一下成果
到这里,我们就把查看部门列表的功能完成了,自己动手写的程序很有成就吧,大家还是要自己动手写写,自己写和直接复制,最后的效果是不一样的,自己写的代码,我们经过了思考和调错,也锻炼了自己的逻辑。
点击详情,也需要根据数据库中查的数据返回–%>
<%-- 注意:前端提交数据的格式是http://localhost:8080/myoa01/dept/list?name=value
我们要根据部门编号来返回对应的信息的话,就应该要让后端能够接收到我们要查询哪一个部门的信息–%>
在之前部门列表页面 的超链接要改成下面:
”>详情
这个路径对应一个Servlet
下面这个是部门详情的Servlet代码
当我们在浏览器点击详情,应该能够根据这个位置的部门编号来返回相关的信息,所以写的路径就是一个技巧。
<%=request.getContextPath()+“/dept/detail?deptno=”+deptno%>把部门编号传给后台,我们根据这个参数名来获取值,进而可以查询到相关数据。
/**
* 部门详情功能,点击详情,根据部门编号返回相应的数据
* @param request
* @param response
*/
private void doDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 首先获取前端浏览器传过来的部门编号信息
* 根据这个信息来查询对应的信息
* 然后返回给详情页面进行展示
*/
String deptno = request.getParameter("deptno");
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
List<User> list=new ArrayList<>();
try {
conn=DBUtils.getConnection();
String sql="select dname,loc from dept where deptno=?";
ps=conn.prepareStatement(sql);
ps.setString(1,deptno);
rs=ps.executeQuery();
//查到数据,返回
while (rs.next()){
User user=new User();
user.setDeptno(deptno);
user.setDname(rs.getString(1));
user.setLoc(rs.getString(2));
list.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.close(conn,ps,rs);
}
//把数据给JSP
// 使用转发,因为需要取数据
request.setAttribute("list",list);
request.getRequestDispatcher("/detail.jsp").forward(request,response);
}
详情页面detail.jsp,可以看到之前写死的数据现在都可以动态获取了,这就是JSP的一个优点,可以动态展示页面。
<%@ page import="com.zyh.oa.javabean.User" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>详情页面</h1>
<%--取出servlet中转发的数据--%>
<%
List<User> userList=(List<User>) request.getAttribute("list");
for(User user:userList){
String deptno = user.getDeptno();
String dname = user.getDname();
String loc = user.getLoc();
//<%--我们可以看到部门的具体信息,点击后退就回到列表页面--%>
部门编号:<%=deptno%> <br>
部门名称:<%=dname%><br>
部门位置:<%=loc%><br>
<%
}
%>
<input type="button" value="后退" onclick="window.history.back()"/>
</body>
</html>
接下来测试一下,这个功能能不能使用
然后点击后退
再点击详情
经过测试,发现功能没有问题,那我们就继续下一个功能模块了。
当我们在部门列表页面点击新增部门的时候,会跳出一个页面,让我们写新增部门的相关信息,当我们点击保存的时候,应该对应一个Servlet程序,把内容存到数据库中,然后跳转到部门列表页面。
add.jsp
Servlet根据前端传入的参数来获取数据,进而插入数据库中
保存成功,重定向到部门列表页面
/**
* 新增部门
* @param request
* @param response
*/
private void doAdd(HttpServletRequest request, HttpServletResponse response) throws IOException {
/**
* 根据获取的参数,来存入数据库中
*/
String deptno = request.getParameter("deptno");
String dname = request.getParameter("dname");
String loc = request.getParameter("loc");
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
int cnt=0;
try {
conn=DBUtils.getConnection();
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);
cnt = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.close(conn,ps,rs);
}
if (cnt>0){
//说明保存成功,跳转到部门列表页面
response.sendRedirect(request.getContextPath()+"/dept/list");
}
}
点击修改,其实应该把对应的数据查询出来,显示在页面上,然后当我们点击修改的时候,把数据保存到数据库中,然后回到部门列表页面
这里我截取重要代码,首先修改功能的第一步应该和详情的功能是一样的,我们可以根据参数值的不同来决定是执行详情功能还是修改功能
<a href="<%=request.getContextPath()+"/dept/detail?deptno="+deptno+"&f=detail"%>">详情</a>
<%-- 点击修改,其实应该把对应的数据查询出来,显示在页面上,然后当我们点击修改的时候,
把数据保存到数据库中,然后回到部门列表页面--%>
<a href="<%=request.getContextPath()+"/dept/detail?deptno="+deptno+"&f=edit"%>">修改</a>
然后在edit.jsp这个修改页面展示数据,来给我们修改,修改后再执行一个servlet,修改数据库中的数据
<%@ page import="com.zyh.oa.javabean.User" %>
<%@ page import="java.util.List" %><%--
Created by IntelliJ IDEA.
User: 17614
Date: 2022-03-30
Time: 19:18
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h1>修改页面h1>
<%--修改页面应该是先返回对应的信息,然后我们点击修改,就可以修改里面的数据
要先保存到数据库里面,然后再展示出来--%>
修改成功后回到列表页面
response.sendRedirect(request.getContextPath()+"/dept/list");
前端把要删除的部门编号传给后端,后端根据这个来删除
<a href="<%=request.getContextPath()+"/dept/delete?deptno="+deptno%>">删除</a>
接下来展示一下效果
然后点击删除
本次的练手小项目先到这里,这个项目还有可以改进的地方,我在下一篇文章会写出来。
链接:https://pan.baidu.com/s/13_copfi8Gqo56MyPaXF18Q?pwd=40xa
提取码:40xa