系列链接:
✨JavaWeb项目实战亲自动手手敲上线小项目的第一天✨
✨JavaWeb项目实战亲自动手手敲上线小项目的第二天✨
✨JavaWeb项目实战亲自动手手敲上线小项目的第三天✨
✨JavaWeb项目:实战亲自动手手敲上线小项目部分功能的第四天优化✨

JavaWeb项目实战第一天进展

  • 项目实现步骤
    • 知识点复习
    • 项目实现过程
    • 实现流程思想与过程
      • 1. 登录功能实现
      • 2. 退出功能实现
      • 3. 学员列表展示

那这次通过一个上线项目中提取出的一个模块,让我们熟悉项目开发过程中的开发流
程以及代码结构,希望大家以此为基石,将代码写的越来越完美。

项目实现步骤

目的是通过这次项目的实现,贯穿前面所学的知识点,让大家能够灵活应用所学知识,解决实际问题。知识点是固定的,但是实现思路是各有千秋的。。所以大家在学习时,不要一味地复制代码或者照抄代码,理解里面的实现过程才是核心。学习实现功能的思路。

学习重点:

  1. 知识点在项目中的应用
  2. 功能实现的逻辑思路

知识点复习

  1. 数据库
  2. JDBC
  3. html
  4. servlet
  5. JSP+EL+JSTL
  6. AJAX
  7. 多表操作

那这个知识点相关的JavaWeb项目其实是包含两天的量的,我第一天没敲完,所以先把知识点给大家摆出来。

项目实现过程

资源包如下:不想手敲的可以直接导入,里面都有,为了大家能够学习,只要2积分:手敲第一天第二天的JavaWeb项目实战对应资源包.zip
再次提醒学习此项目是需要该资源包的,要不然你看到的只是思路与我的实现过程,你们是没办法实现的,因为我不可能将一个项目的所有代码都展示出来,那太多了,光js都要上千行的,还有许多图片要插入的,所以如果想要跟进本项目的可以下载资源包,那不想下载的,只想白嫖的,或者就是学习一下思路的,我也十分欢迎,谢谢大家的浏览,也希望你本次的浏览能有所收获。
那我在多说一句就是如果大家真的有心想要跟进这个小项目的话,我建议大家把src目录下的所有代码全都删除,然后一步步的重新自己去实现,也许要花费你一个星期甚至更长的时间,但是这是值得的,再怎么说这也是个小项目,再不济都是可以写到简历项目经理的,虽然他很简单,但是你如果一步一步都会了理解了,那你的水平也是能让人信服的。
当然白嫖是不可能让你们白嫖的,真想白嫖的,留言的评论让我觉得好的,我点赞的,私信你加好友,给你发。我就是这样实在,我可真不错。

  1. 分析静态页面,根据html或需求创建数据库
  2. 填写测试数据(sql语句添加)
  3. 创建项目,包结构(bean,dao.impl,servlet,service.impl,util),修改html页面为jsp(html->jsp)
    (1)在HTML中添加page指令
    (2) 将html的后缀改成jsp
  4. 填写内容(注意填写顺序)
    4.1 bean:属性,封装方法,无参构造,全参构造
    ​      表名=类名 ,列名=属性名
    4.2 dao包:操作方法的接口,命名:实体类名+Dao,
    ​       Dbutils(属性文件,*.properties)
    4.3 impl包:命名: 接口名+Impl
    ​       实现接口,继承Dbutils
    4.4 service.impl
    ​       service定义的是接口,接口中的方法和dao层接口中的方法一致
    ​        impl : 这层的实现类主要负责调取dao层方法
    4.5 servlet:
    ​       4.5.1. 接受参数
    ​       4.5.2. 调取service层的方法,service又在调取dao层的方法
    ​       4.5.3. 根据结果跳转页面
    核心:jsp页面负责发送请求和展示数据

实现流程思想与过程

那基本的想法实现过程已经分析过了,那就开始实现吧!
那我先把包结构给大家展示出来,包结构是提前建好了,之后两天往里填充内容。
实现的方式就是采用了MVC框架

1. 登录功能实现

  1. 我们首先去访问login.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>用户登录</title><link href="css/login.css" type="text/css" rel="stylesheet" /></head>
<body id="userlogin_body">
<form action="login" method="post">
<div id="user_login"><dl><dd id="user_top"><ul><li class="user_top_l"></li><li class="user_top_c"></li><li class="user_top_r"></li></ul></dd><dd id="user_main"><ul><li class="user_main_l"></li><li class="user_main_c"><div class="user_main_box"><ul><li class="user_main_text">用户名: </li><li class="user_main_input"><input name="username" maxlength="20" id="TxtUserName" class="txtusernamecssclass"> </li></ul><ul><li class="user_main_text">密 码: </li><li class="user_main_input"><input type="password" name="password" id="TxtPassword" class="txtpasswordcssclass"> </li></ul></div></li><li class="user_main_r"><a href="index.jsp"><input type="image" name="IbtnEnter" src="img/user_botton.gif" class="ibtnentercssclass"></a></li></ul></dd><dd id="user_bottom"><ul><li class="user_bottom_l"></li><li class="user_bottom_c"></li><li class="user_bottom_r"></li></ul></dd></dl>
</div>
</form></body>
</html>

当然了,光有login.jsp,不发里面的css样式就很狗,所以login.css样式如下:

@charset "utf-8";
*{margin:0;padding:0;list-style-type:none;}
a,img{border:0;}
body{font:12px/180% Arial, Helvetica, sans-serif, "新宋体";}#userlogin_body{background:url(../img/user_all_bg.gif) #226cc5 repeat-x 50% top;margin:110px 0px 0px;font:12px/150% arial, "宋体" ,helvetica,sans-serif;text-decoration:none}
#user_login{margin:0px auto;width:590px}
#user_top,#user_main,#user_bottom{clear:both}
#user_top li,#user_main li,#user_bottom li{float:left;}
.user_top_r{background:url(../img/user_top_r.gif) no-repeat 50% top}
.user_top_c{background:url(../img/user_top_c.gif) no-repeat 50% top}
.user_top_l{background:url(../img/user_top_l.gif) no-repeat 50% top}
.user_main_r{background:url(../img/user_main_r.gif) #bec5cc no-repeat 50% top}
.user_main_c{background:url(../img/user_main_c.gif) #bec5cc no-repeat 50% top;width:280px}
.user_main_l{background:url(../img/user_main_l.gif) #bec5cc no-repeat 50% top}
.user_bottom_r{background:url(../img/user_bottom_r.gif) no-repeat 50% top}
.user_bottom_c{background:url(../img/user_bottom_c.gif) no-repeat 50% top;color:#fff;line-height:117px;padding-top:20px;text-align:right}
.user_bottom_c a{color:yellow;text-decoration:underline}
.user_bottom_c a:hover{color:#c00}
.user_bottom_l{background:url(../img/user_bottom_l.gif) no-repeat 50% top}
.user_top_r,.user_main_r,.user_bottom_r{float:left;width:180px}
.user_main_c,.user_top_c,.user_bottom_c{float:left;width:280px}
.user_top_l,.user_main_l,.user_bottom_l{float:left;width:129px}
.user_top_r,.user_top_c,.user_top_l{height:116px}
.user_main_r,.user_main_c,.user_main_l{height:139px}
.user_bottom_r,.user_bottom_c,.user_bottom_l{height:117px}
.user_main_r{line-height:139px}
.user_main_box ul{clear:both}
.user_main_box li{float:left;}
.user_main_box .user_main_text{line-height:34px;height:34px}
.user_main_box .user_main_input{line-height:34px;height:34px}
.user_main_box .user_main_text{width:60px;color:#000}
.user_main_box .user_main_input img{margin-bottom:-2px;margin-left:-25px}
.txtusernamecssclass{border-top-width:0px;padding-left:25px;border-left-width:0px;background:url(../img/user_login_name.gif) no-repeat;border-bottom-width:0px;width:165px;line-height:20px;height:21px;border-right-width:0px}
.txtpasswordcssclass{border-top-width:0px;padding-left:25px;border-left-width:0px;background:url(../img/user_login_password.gif) no-repeat;border-bottom-width:0px;width:165px;line-height:20px;height:21px;border-right-width:0px}
.ibtnentercssclass{width:111px;height:122px;border:0;}

那里面的图片没有也很丑,所以img下的图片,这个我还真发不了啊,总不能一张一张截吧,所以还是建议大家下载上面的资源包,只有2积分,不是没觉得0积分更好,就是觉得那样感觉大家会觉得得到的东西太容易,你们反而不学了,那其实有没有样式都不重要,最重要的是实现功能,所以没有也行,当然这个项目我还会更新的。

好,言归正传,我们看这段代码

<input type="image" name="IbtnEnter" src="img/user_botton.gif" class="ibtnentercssclass">

当用户点击<input type="image">(图片提交)提交按钮的时候,我们会传入一个usernamepassword,
之后发送一个请求给action(form表单),

<form action="login" method="post">

那action的请求地址是login,会找到login的处理类:LoginServlet

  1. 那我们的LoginServlet会干什么事呢?

    2.1. 接收参数(username,password).2.2. 调取service的login方法,
    
package com.lby.web;import com.lby.bean.Users;
import com.lby.service.impl.UsersServiceImpl;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.io.PrintWriter;/*** @Author: King-lby* @Date Created in 2021-08-24 9:56*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1. 接收参数String username = req.getParameter("username");String password = req.getParameter("password");//2. 调取serviceUsersServiceImpl usersService = new UsersServiceImpl();Users users = usersService.login(username, password);//3. 跳转页面}}
}

所以我们的UsersService接口:

package com.lby.service;import com.lby.bean.Users;/*** @Author: King-lby* @Date Created in 2021-08-24 9:46*/
public interface UsersService {/*** 登录方法*/public Users login(String username,String password);
}

还有我们的UsersServiceImpl实现类:

package com.lby.service.impl;import com.lby.bean.Users;
import com.lby.dao.UsersDao;
import com.lby.dao.impl.UsersDaoImpl;
import com.lby.service.UsersService;/*** @Author: King-lby* @Date Created in 2021-08-24 9:47*/
public class UsersServiceImpl implements UsersService {private UsersDao usersDao = new UsersDaoImpl();@Overridepublic Users login(String username, String password) {return usersDao.login(username, password);}
}

那我们调用service的login之后,我们的service还要去调用dao层:所以我们的UsersDao接口是:

package com.lby.dao;import com.lby.bean.Users;/*** @Author: King-lby* @Date Created in 2021-08-24 9:46*/
public interface UsersDao {/*** 登录方法*/public Users login(String username, String password);
}

还有我们的UsersDaoImpl实现类:

package com.lby.dao.impl;import com.lby.bean.Users;
import com.lby.dao.DBUtils;
import com.lby.dao.UsersDao;import javax.xml.registry.infomodel.User;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;/*** @Author: King-lby* @Date Created in 2021-08-24 9:47*/
public class UsersDaoImpl extends DBUtils implements UsersDao {@Overridepublic Users login(String username, String password) {return null;}
}

而dao层负责往数据库中进行传输,那就用到了我们的DBUtils工具类.

package com.lby.dao;import com.alibaba.druid.pool.DruidDataSource;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;public class DBUtils {//1.定义变量private Connection connection;private PreparedStatement pps;private ResultSet resultSet;private int count;//存储收影响的行数private static String userName;private static String userPass;private static String url;private static String dirverName;//德鲁伊private static DruidDataSource dataSource=new DruidDataSource();//2.加载驱动static {//德鲁伊ResourceBundle bundle = ResourceBundle.getBundle("jdbc");dirverName = bundle.getString("driverClassName");url = bundle.getString("url");userName = bundle.getString("username");userPass = bundle.getString("password");dataSource.setUsername(userName);dataSource.setPassword(userPass);dataSource.setUrl(url);dataSource.setDriverClassName(dirverName);// dataSource.setInitialSize(20);}//3.获得链接protected  Connection getConnection(){try {connection=dataSource.getConnection();} catch (SQLException throwables) {throwables.printStackTrace();}return connection;}//4.得到预状态通道protected  PreparedStatement getPps(String sql){try {pps= getConnection().prepareStatement(sql);} catch (SQLException throwables) {throwables.printStackTrace();}return pps;}//5.绑定参数  List保存的是给占位符所赋的值protected  void param(List list){if(list!=null&&list.size()>0){for (int i=0;i<list.size();i++) {try {pps.setObject(i+1,list.get(i));} catch (SQLException throwables) {throwables.printStackTrace();}}}}//6.执行操作(增删改+查询)protected  int  update(String sql,List list){getPps(sql);param(list);try {count= pps.executeUpdate();} catch (SQLException throwables) {throwables.printStackTrace();}return count;}//7.查询protected  ResultSet query(String sql,List list){getPps(sql);param(list);try {resultSet= pps.executeQuery();} catch (SQLException throwables) {throwables.printStackTrace();}return resultSet;}//8.关闭资源protected  void closeAll(){try {if (connection != null) {connection.close();}if (pps != null) {pps.close();}if (resultSet != null) {resultSet.close();}} catch (SQLException throwables) {throwables.printStackTrace();}}}

当然由于我们是使用的德鲁伊连接池,所以我们用一个.properties文件来放我们的数据库链接内容
所以我们的jdbc.properties是这样的:(那我创建的数据库名为:student,账号密码都是默认root,大家可根据自己的建库内容进行修改)

//主要是前面的四条
url=jdbc:mysql://localhost:3306/student?serverTimezone=UTC
username=root
password=root
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10
minIdle=5
maxWait=3000

好,一切配置就绪,哎,还有一个,当然还有我们的bean目录下的Users了:

package com.lby.bean;/*** @Author: King-lby* @Date Created in 2021-08-24 9:35*/
public class Users {private Integer userId;private String loginName;private String passWord;private String realName;public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) {this.passWord = passWord;}public String getRealName() {return realName;}public void setRealName(String realName) {this.realName = realName;}
}

好,我们接着来分析思路,那在我们调取dao层的方法,我们首先就是写一个sql语句去查询我们的登录账户和密码,

String sql = "select * from users where loginname=? and password=? ";

之后去添加参数到ArrayList集合,

//将username与password放入ArrayList集合中ArrayList arrayList = new ArrayList();arrayList.add(username);arrayList.add(password);

然后返回结果集,对其进行0值判断

 resultSet = query(sql, arrayList);if (resultSet==null){return null;}

注意,这里会报错,因为我们的DBUtils中的ResultSet属性的权限修饰符为private,所以我们将其改为protected就好了。

protected ResultSet resultSet;

之后查询对应数据

while (resultSet.next()) {users=new Users();users.setLoginName(username);users.setRealName(resultSet.getString("realname"));users.setUserId(resultSet.getInt("userid"));}

之后try/catch/finally就好了。
那具体步骤如下:

我们查询数据是首先要在login方法中的最外层设置Users users = null;设置一个users的空值对象,那这个对象其实是在将结果集的数据进行封装的while循环中users=new Users();new的。最后closeALL();关闭资源。返回users.

那完整的UsersDaoImpl的实现代码如下:

package com.lby.dao.impl;import com.lby.bean.Users;
import com.lby.dao.DBUtils;
import com.lby.dao.UsersDao;import javax.xml.registry.infomodel.User;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;/*** @Author: King-lby* @Date Created in 2021-08-24 9:47*/
public class UsersDaoImpl extends DBUtils implements UsersDao {@Overridepublic Users login(String username, String password) {Users users = null;try {String sql = "select * from users where loginname=? and password=? ";//将username与password放入ArrayList集合中ArrayList arrayList = new ArrayList();arrayList.add(username);arrayList.add(password);//封装查询条件并返回结果集resultSet = query(sql, arrayList);if (resultSet==null){return null;}//将结果集的数据进行包装while (resultSet.next()) {users=new Users();users.setLoginName(username);users.setRealName(resultSet.getString("realname"));users.setUserId(resultSet.getInt("userid"));}} catch (SQLException throwables) {throwables.printStackTrace();} finally {closeAll();}return users;}
}
  2.3.那我们回过头来继续往下看我们的LoginServlet,第三步在执行了service之后根据查询结果去跳转页面,我们首先去做一个对users对象中是否存在我们存储的内容的一个空值判定,并且我们以弹窗方式提示用户,登录失败
 //3. 跳转页面if (users==null){//以弹窗方式提示用户,登录失败resp.setContentType("text/html; charset=UTF-8");PrintWriter writer = resp.getWriter();writer.println("<script>location.href='login.jsp';alert('用户名或密码不正确');</script>");}else{//跳转到主页面//保存用户信息req.getSession().setAttribute("u1",users);resp.sendRedirect("index.jsp");}

那这里我们可以先去设置一个编码格式:html,使客户端浏览器,能识别出咱们的数据,然后我们写一个打印输出流,让我们数据打印出来,我们在里面采用弹窗方式提示用户信息有误,并且点击确定返回我们的登录页面让用户重新输入信息。


那到这里,我们的登录效果就做好了,那以下就是我们登录的几种情况:

  1. 登录页面展示:
    2. 登录失败页面:
    3. 登陆成功页面:

2. 退出功能实现

那说完了登录再来说说我们的退出。那这次退出我们采用的是会话的方式,那一旦退出,会话结束,账户密码信息也就会被消除。

  1. head.jsp中的登录用户后面,写一个退出的超链接,(上面图片右上角有个退出键即为效果)。
    那我们的head.jsp就是这样的:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head><meta http-equiv=content-type content="text/html; charset=utf-8" /><link href="./css/admin.css" type="text/css" rel="stylesheet" /></head><body><table cellspacing=0 cellpadding=0 width="100%" background="./img/header_bg.jpg" border=0><tr height=56><td width=260><!--<img height=56 src="img/header_left.jpg"  width=260>--></td><td style="font-weight: bold; color: #fff; padding-top: 20px" align=middle> <!-- οnclick="if (confirm('确定要退出吗?')) return true; else return false;"  --></td><td style="font-weight: bold; color: #fff; padding-top: 20px" align="right"><%--LoginServlet中的u1是一个用户对象,如果想要得到其中的属性。直接.属性(去bean中找)--%>当前用户:${u1.loginName} &nbsp;&nbsp;<a href="loginout">退出</a></td></tr></table><table cellspacing=0 cellpadding=0 width="100%" border=0><tr bgcolor=#1c5db6 height=4><td></td></tr></table></body>
</html>

那在我们点击退出的超链接也就是发送我们的请求到loginout,也就是地址请求发送到LoginOutServlet

  1. 那我们的LoginOutServlet会干什么事呢?

    2.1. 使用用req.getSession().invalidate();2.2. 调取service的login方法,之后进行重定向或者转发进行页面的跳转,回到我们的登录页面。
    
package com.lby.web;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;/*** @Author: King-lby* @Date Created in 2021-08-24 11:35*/
@WebServlet("/loginout")
public class LoginOutServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//清除sessionreq.getSession().invalidate();//使session失效//重定向//resp.sendRedirect("/login.jsp");//结果发现只有head步退出,剩下的没有退出,因为使用了frameset框架,所以换种方式resp.setContentType("text/html; charset=UTF-8");resp.getWriter().println("<script>alert('退出成功');top.location.href='login.jsp'</script>");}
}

那我们的目的是什么?

  1. 首先让我们的会话失效,那失效了,其中的数据也就不在了,就实现了我们的退出的目的。
  2. 那之后的页面跳转我们去思考一下,到底哪个方式好一点。
    2.1. 我们首先去假定我们采用的是重定向的方式,那我们的代码就是这样的        resp.sendRedirect("/login.jsp");,结果是只有head.jsp的部分进行了退出,而剩下
           部分都没有退出,原因是,这个项目是比较老了,采用的是frameset框架,那因为frameset
           框架,每个框架存有独立的文档,所以它只会在自己的jsp部分进行退出,当然正是因为项目
           有点老,获取资源也就相对简单,像这样的小项目网上有很多,大家可以自行探索。
    那我们就换种方法采用getWriter打印输出流,然后里面嵌套<script></script>标签,进行本页面的跳转,和登录一样。

那退出的功能就是如此,我们的效果展示如下:
当我们在登录成功后,点击退出,会显示:
那之后我们直接通过地址访问我们的登录主页面,就会是这样的:
可以看到,我们原来的user1不见了,这就说明我们退出成功了,把账户密码信息都删除了。

3. 学员列表展示

同样的,这个页面的实现也是和登录三步一样.
当用户在点击左侧的学生管理(left.jsp)时,发送请求,然后就发送一个请求地址Educational/student/getStudentList到GetStudentServlet

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head><meta http-equiv=content-type content="text/html; charset=utf-8"/><link href="css/admin.css" type="text/css" rel="stylesheet"/><script language=javascript>function expand(el) {childobj = document.getElementById("child" + el);if (childobj.style.display == 'none') {childobj.style.display = 'block';} else {childobj.style.display = 'none';}return;}</script>
</head>
<body background=img/menu_bg.jpg>
<table height="100%" cellspacing=0 cellpadding=0 width=170 background=./img/menu_bg.jpg border=0><tr><td valign=top align=middle><table cellspacing=0 cellpadding=0 width="100%" border=0><tr><td height=10></td></tr></table><table cellspacing=0 cellpadding=0 width=150 border=0><tr height=22><td style="padding-left: 30px" background=./img/menu_bt.jpg><a class=menuparent onclick=expand(2) href="javascript:void(0);">教务中心</a></td></tr><tr height=4><td></td></tr></table><table id=child2 style="display: none" cellspacing=0 cellpadding=0 width=150 border=0><tr height=20><td align=middle width=30><img height=9 src="./img/menu_icon.gif" width=9></td><td><%--这里就是我们的a标签超链接请求--%><a class=menuchild href="Educational/student/getStudentList" target="right">学生管理</a></td></tr><tr height=4><td colspan=2></td></tr></table></td><td width=1 bgcolor=#d1e6f7></td></tr>
</table>
</body>
</html>
  1. 那我们的GetStudentServlet会干什么事呢?

    2.1 接收参数(暂无参数,可以不用写)
    2.2. 调取service的getStudents方法(将所有数据都查询出来,之后根据条件进行限定条件的筛选),
    
package com.lby.web;import com.lby.bean.Student;
import com.lby.service.StudentService;
import com.lby.service.impl.StudentServiceImpl;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.util.List;/*** @Author: King-lby* @Date Created in 2021-08-24 16:37*/
@WebServlet("/Educational/student/getStudentList")
public class GetStudentServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1. 获取参数//2. 调取service方法StudentServiceImpl service = new StudentServiceImpl();List<Student> students = service.getStudents();//3. 跳转页面}
}

所以我们的StudentService接口:

package com.lby.service;import com.lby.bean.Student;import java.util.List;/*** @Author: King-lby* @Date Created in 2021-08-24 9:46*/
public interface StudentService {/*** 获取学员的信息列表*/public List<Student> getStudents();
}

那我们的StudentServiceImpl实现类如下:

package com.lby.service.impl;import com.lby.bean.Student;
import com.lby.dao.StudentDao;
import com.lby.dao.impl.StudentDaoImpl;
import com.lby.service.StudentService;import java.util.List;/*** @Author: King-lby* @Date Created in 2021-08-24 9:47*/
public class StudentServiceImpl implements StudentService {private StudentDao dao = new StudentDaoImpl();@Overridepublic List<Student> getStudents() {return dao.getStudents();}
}

我们调用service的getStudents之后,我们的service还要去调用dao层:所以我们的StudentDao接口是:

package com.lby.dao;import com.lby.bean.Student;import java.util.List;/*** @Author: King-lby* @Date Created in 2021-08-24 9:46*/
public interface StudentDao {/*** 获取学员的信息列表*/public List<Student> getStudents();
}

还有我们的StudentDaoImpl实现类:

package com.lby.dao.impl;import com.lby.bean.Student;
import com.lby.dao.DBUtils;
import com.lby.dao.StudentDao;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/*** @Author: King-lby* @Date Created in 2021-08-24 9:47*/
public class StudentDaoImpl extends DBUtils implements StudentDao {@Overridepublic List<Student> getStudents() {return null;}
}

当然不要忘了我们的bean目录下的Student:

package com.lby.bean;import java.util.Date;/*** @Author: King-lby* @Date Created in 2021-08-24 9:36*//*** 学生信息表*/
public class Student {private Integer stuId;//编号private String stuName;//学生名字private String stuNo;//学生编号private Integer sex;//性别(0,1)0是什么,1是什么自己猜private String phone;//电话private String email;//邮箱private String registered;//注册地址(省级)private String address;//详细地址private String profession;//学科private String idNumber;//学号private String politics;//身份private Date regDate;//注册日期private Integer state;//状态private String introduction;//学生描述private Integer gid;//年级号,外键private Grade grade;//因为有外键,所以要和grade表有关联public Integer getStuId() {return stuId;}public void setStuId(Integer stuId) {this.stuId = stuId;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}public String getStuNo() {return stuNo;}public void setStuNo(String stuNo) {this.stuNo = stuNo;}public Integer getSex() {return sex;}public void setSex(Integer sex) {this.sex = sex;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getRegistered() {return registered;}public void setRegistered(String registered) {this.registered = registered;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String getProfession() {return profession;}public void setProfession(String profession) {this.profession = profession;}public String getIdNumber() {return idNumber;}public void setIdNumber(String idNumber) {this.idNumber = idNumber;}public String getPolitics() {return politics;}public void setPolitics(String politics) {this.politics = politics;}public Date getRegDate() {return regDate;}public void setRegDate(Date regDate) {this.regDate = regDate;}public Integer getState() {return state;}public void setState(Integer state) {this.state = state;}public String getIntroduction() {return introduction;}public void setIntroduction(String introduction) {this.introduction = introduction;}public Integer getGid() {return gid;}public void setGid(Integer gid) {this.gid = gid;}public Grade getGrade() {return grade;}public void setGrade(Grade grade) {this.grade = grade;}
}

而dao层负责往数据库中进行传输,那就用到了我们的DBUtils工具类.之后我们首先就是写一个sql语句去查询我们的学生列表信息

 String sql="select * from student";

返回结果集,

 resultSet = query(sql, null);//没有参数,返回结果集,使用父类变量resultSet

之后查询对应数据

while(resultSet.next()){Student student = new Student();student.setStuId(resultSet.getInt("stuid"));student.setStuNo(resultSet.getString("stuno"));student.setStuName(resultSet.getString("stuname"));student.setSex(resultSet.getInt("sex"));student.setPhone(resultSet.getString("phone"));student.setProfession(resultSet.getString("profession"));student.setRegDate(resultSet.getDate("regdate"));student.setEmail(resultSet.getString("email"));student.setRegistered(resultSet.getString("registered"));student.setAddress(resultSet.getString("address"));student.setIdNumber(resultSet.getString("idNumber"));student.setPolitics(resultSet.getString("politics"));student.setState(resultSet.getInt("state"));student.setIntroduction(resultSet.getString("introduction"));student.setGid(resultSet.getInt("gid"));

然后将我们的数据放到我们new的一个Arraylist集合中,那这个new的集合是局部变量,所以设在getStudents方法中的最外层,那之后我们就可以

 list.add(student);//将student对象添加到list集合中

之后try/catch/finally就好了。
那具体步骤如下:

我们将new一个Student对象,之后在while循环中查询数据(最好是将所有的数据都查询到,以便之后想查询哪个就去调用哪个),返回给结果集。之后将student对象添加到list集合中,最后closeALL();关闭资源。,返回list集合。

那完整的StudentDaoImpl的实现代码如下:

package com.lby.dao.impl;import com.lby.bean.Student;
import com.lby.dao.DBUtils;
import com.lby.dao.StudentDao;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/*** @Author: King-lby* @Date Created in 2021-08-24 9:47*/
public class StudentDaoImpl extends DBUtils implements StudentDao {@Overridepublic List<Student> getStudents() {List list = new ArrayList<Student>();try {String sql="select * from student";resultSet = query(sql, null);//没有参数,返回结果集,使用父类变量resultSetwhile(resultSet.next()){Student student = new Student();student.setStuId(resultSet.getInt("stuid"));student.setStuNo(resultSet.getString("stuno"));student.setStuName(resultSet.getString("stuname"));student.setSex(resultSet.getInt("sex"));student.setPhone(resultSet.getString("phone"));student.setProfession(resultSet.getString("profession"));student.setRegDate(resultSet.getDate("regdate"));student.setEmail(resultSet.getString("email"));student.setRegistered(resultSet.getString("registered"));student.setAddress(resultSet.getString("address"));student.setIdNumber(resultSet.getString("idNumber"));student.setPolitics(resultSet.getString("politics"));student.setState(resultSet.getInt("state"));student.setIntroduction(resultSet.getString("introduction"));student.setGid(resultSet.getInt("gid"));list.add(student);//将student对象添加到list集合中}} catch (SQLException throwables) {throwables.printStackTrace();} finally {closeAll();//关闭所有资源}return list;//返回list}
}
2.3 那我们回过头来继续往下,第三步在执行了service之后根据查询结果得到一个学生集合List<Student>,
那我们这个学生集合的信息当然要去显示,所以就去跳转到展示页面,那既然要去跳转到展示页面,
那就要从后台往前台传数据,那要传数据就要先去存数据。
//3. 跳转页面//如果后台想给前台传数据,是一定要给给前台存值的req.setAttribute("stulist",students);//将students对象的数据存到stulist中

好,存完之后就要去跳转页面了,那跳转页面的方式有两种,一种是重定向,一种是转发。
注意:重定向会丢失数据的,它会丢失request中的数据,那我们的目的就是存值然后在页面去展示这些数据,那一重定向,数据没了,展示个什么劲啊!
所以我们用转发之后我们跳转到list.jsp,看展示数据。

req.getRequestDispatcher("list.jsp").forward(req,resp);

那跳转到list.jsp查看展示数据:
那我们可以用一个jstl标签库中的<c:forEach></c:forEach>去循环查询动态数据并展示。当然这个首先要有jstl的jar包,然后在list.jsp中添加标签库

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

那我们的list.jsp就修改为:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>学生信息管理平台</title>
<link href="../../Style/StudentStyle.css" rel="stylesheet" type="text/css" />
<link href="../../Script/jBox/Skins/Blue/jbox.css" rel="stylesheet" type="text/css" />
<link href="../../Style/ks.css" rel="stylesheet" type="text/css" />
<link href="../../css/mine.css" type="text/css" rel="stylesheet">
<script src="../../Script/jBox/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="../../Script/jBox/jquery.jBox-2.3.min.js"type="text/javascript"></script>
<script src="../../Script/jBox/i18n/jquery.jBox-zh-CN.js"type="text/javascript"></script>
<script src="../../Script/Common.js" type="text/javascript"></script>
<script src="../../Script/Data.js" type="text/javascript"></script><script>function del(){confirm("确认操作?");}</script></head>
<body><div class="div_head" style="width: 100%;text-align:center;"><span><span style="float: left;">当前位置是:教务中心-》学生管理</span><span style="float: right; margin-right: 8px; font-weight: bold;"><a style="text-decoration: none;" href="/Educational/student/getGradeList">【新增学生】</a>&emsp;&emsp;&emsp;&emsp;</span></span></div><div class="cztable"><div><form action="#" method="get">学生名称: <input type="text"/>学生学号: <input type="text"/>性别: <select ><option>--请选择--</option><option>男</option><option >女</option></select><input type="button" value="查询" /></form><table width="100%" border="0" cellspacing="0" cellpadding="0"><tbody><tr style="height: 25px" align="center"><th >学号</th><th width="">姓名</th><th width="">性别</th><th width="15%">联系电话</th>                        <th width="15%">专业</th><th width="15%">登记时间</th><th>操作</th></tr><%--循环--%><c:forEach items="${stulist}" var="stu" ><tr id="product1"><td align="center">${stu.stuNo}</td><td align="center">${stu.stuName}</td><td align="center">${stu.sex==1?'男':'女'}</td><td align="center">${stu.phone}</td><td align="center">${stu.profession}</td><td align="center">${stu.regDate}</td><td align="center"><a href="/Educational/student/findbyid?sid=${stu.stuId}">修改</a><a href="/Educational/student/deletebyid?sid=${stu.stuId}">删除</a></td>                                   </tr></c:forEach><tr><td colspan="20" style="text-align: center;"><a style="text-decoration: none;" href="#">首页 上一页 ... 7 8 9 10 11 12 ...下一页 尾页 共1234条 每页显示 10/23</a></td></tr></tbody></table></div></div></div></div>
</body>
</html>

那最后的效果展示就是这样的:

那由于本人的无能,所以今天只能理解到这里,内容有点少,希望那个大家见谅。
当然若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。
别问,问就是
创作不易,白嫖很爽,但是求各位手下留情。
如果本篇博客有任何错误或者疏漏,请批评斧正,感激不尽 !

✨JavaWeb项目:实战亲自动手手敲上线小项目部分功能的第一天✨相关推荐

  1. 【机器学习】PCA主成分项目实战:MNIST手写数据集分类

    PCA主成分项目实战:MNIST手写数据集分类 PCA处理手写数字集 1 模块加载与数据导入 2 模型创建与应用 手动反爬虫:原博地址 https://blog.csdn.net/lys_828/ar ...

  2. Python和Java结合的项目实战_[项目实战] Python高级教程项目实战篇 Python和Java结合的项目实战 视频教程 [...

    资源介绍 课程简介:xa0xa0 Python高级教程项目实战篇 Python和Java结合的项目实战 视频教程 教学视频 ----------------------课程目录 Python项目实战篇 ...

  3. Spring Boot + vue-element 开发个人博客项目实战教程(二十五、项目完善及扩展(前端部分))

    ⭐ 作者简介:码上言 ⭐ 代表教程:Spring Boot + vue-element 开发个人博客项目实战教程 ⭐专栏内容:零基础学Java.个人博客系统 ⭐我的文档网站:http://xyhwh- ...

  4. spark项目实战:电商分析平台之项目概述

    spark项目实战:电商分析平台之项目概述 目录 项目概述 程序架构分析 需求解析 初始代码和完成代码存放在github上面 1. 项目概述 在访问电商网站时,我们的一些访问行为会产生相应的埋点日志( ...

  5. [嵌入式Linux项目实战开发]基于QT4.8的仓库管理系统实现功能【2019年给力项目】

    [嵌入式Linux项目实战开发]基于QT4.8的仓库管理系统实现功能[2019年给力项目] 支持导出 excel 表格 支持查看商品操作日志 支持高精度浮点运算 支持同一商品以不同价格入库 该软件已开 ...

  6. 《Kotlin从小白到大牛》第28章:项目实战1:开发PetStore宠物商店项目

    第28章 项目实战1:开发PetStore宠物商店项目 前面学习的Kotlin知识只有通过项目贯穿起来,才能将书本中知识变成自己的.通过项目实战读者能够了解软件开发流程,了解所学知识在实际项目中使用的 ...

  7. 《Java从小白到大牛》第29章:项目实战1:开发PetStore宠物商店项目

    第29章 项目实战1:开发PetStore宠物商店项目 前面学习的Java知识只有通过项目贯穿起来,才能将书本中知识变成自己的.通过项目实战读者能够了解软件开发流程,了解所学知识在实际项目中使用的情况 ...

  8. 适合初学者练手的vue小项目(附github源码)

    vue慢慢的成为了前端最受欢迎的框架之一,在很多项目之中开发都能用得到,如今也已经发展到3.0了,可能是因为这个框架可以提高工作效率,因此受到大家的追捧,在之前的文章里面也说过,2019年,大前端学习 ...

  9. 10讲项目实战首页底部固定位置的分享、咨询功能

    #10讲项目实战首页底部固定位置的分享.咨询功能   <!--整站建设步骤如下:   1.构建一个宽度100% 高度149px 这样一个长方形,为了保证浏览器的兼容,我们加了*{margin:0 ...

最新文章

  1. mysql setup choose_1.MySQL安装、启动、登录、重置密码、卸载
  2. APICloud学习第二天——操作云数据库
  3. 深入解读:KubeVela 与 PaaS 有何不同?
  4. 异步非阻塞_细说同步异步、阻塞非阻塞
  5. C++ 标准库 书籍学习记录笔记 第5章
  6. python文件和数据的格式化_Python在文本文件中格式化特定数据
  7. 方维分享系统,品牌无法设置分类关联
  8. oracle数据库表用序列实现主键自增长
  9. 极限学习机和支持向量机_极限学习机的发展
  10. Stata数据处理:清洗中国城市建设统计年鉴
  11. bilibili封面提取
  12. word一键生成ppt 分页_PPT插入word自动分页
  13. 25.JavaScript的Symbol类型、隐藏属性、全局注册表
  14. eclipse改变背景颜色及背景图片
  15. 贝叶斯分类器做文本分类案例
  16. Bazel Remote Caching
  17. 计算机网络双语常用词汇,常用计算机英语词汇:URL
  18. Php大马的简单解密[技巧]
  19. kubeadm初始化集群报错:kubelet driver: “cgroupfs“ is different from docker cgroup driver: “systemd“
  20. 论文 计算机动态网页的制作,计算机动态网页设计中多元素应用网页设计论文(范文1)...

热门文章

  1. 单片机酒精浓度检测仪
  2. CleanMyMac免费苹果MAC系统清理APP
  3. Elasticsearch查询must与should不能同层级使用
  4. 基于物联网及云计算技术的智慧充电桩平台设计方案
  5. 多任务进化优化算法(一)——多因子进化算法(MFEA)
  6. STM32CUBE_IIC_读写EEPROM24C64
  7. python抖音信息采集_初探抖音的数据采集,竟然简单到无脑!
  8. Android Studio Maven仓库设置aliyun、google、jcenter
  9. 加湿器全国产化电子元件推荐方案
  10. eclipse项目的maven工程找不到主类的解决办法