一·bootstrap使用概述(从二·开始是完整流程)
1·bootstrap准备
1)·在“WebContent”下建立文件夹:
vendor:供应商,提供者,第三方库
2)·下载bootstrap:https://getbootstrap.com/
3)·将下载解压后的安装包复制到vendor文件夹下:
4)·在input_student.html添加link(引入样式表)
在图示位置插入link:
复制"css/bootstrap.min.css"的文件路径:
做法:拷贝完全路径:
粘贴到“link”的“href”上:
保留到vendor:
在其前添加应用程序名(绝对路径):
忘记应用程序名的话,如下两张图所示:
5)·容器
使用前:
将的内容用<div class="container"></div>
包起来:
1` <h>的几个样式
1· my-5:margin Y轴,上下外边距,上下保持5个单位的间距,是bootstrap的单位,5是最大
2· mt-5:margin top ,上面保持5个单位的外边距
3· mb-5:margin bottom,下面保持5个单位的外边距:
2` <form>表单的几个样式
1·col-md-6
2·col-12:占满整行,(栅格系统:整行12格
现在运行结果如下:
看起来并没有变化,再进行下面两步。
3`在<form>下的<div>中添加class="form-group"
4`在<form>下的<div>下的<input>中添加class="form-control"
5`以上更改的结果如下:
6`在<button> 中添加 type="submit" class="btn btn-primary"
效果如下:
1·btn:按钮
2·btn-primary:主按钮
3·btn-danger:红色的按钮
4·btn-warning:警告,黄色的按钮
5·btn btn-primary有点大btn btn-primary btn-sm
small小一点
5)·修改后的新生登记如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/stuwork/vendor/bootstrap-4.5.3-dist/css/bootstrap.min.css">
<title>Insert title here</title>
</head>
<body>
<div class="container">
<h3 class="my-5">新生登记</h3>
<form class="col-6" action="stuMgr" method="post">
<input type="hidden" name="task" value="createStu"/>
<div class="form-group">
<label>学生学号:</label>
<input type="text" class="form-control" name="stuno">
</div>
<div class="form-group">
<label>学生姓名:</label>
<input type="text" class="form-control" name="stuname">
</div>
<div class="form-group">
<label>学生成绩:</label>
<input type="text" class="form-control" name="stumark">
</div>
<button type="submit" class="btn btn-primary">新生登记</button>
</form>
</div>
</body>
</html>
二·编写Dao层
1·在“StudentDao”添加
List<Student> loadStus();//泛型,List里面只能包含学生,不能包含别的东西了
修改后的
package edu.mju.stuwork.dao;
import java.util.List;
import edu.mju.stuwork.domain.Student;
public interface StudentDao {
void addStu(Student stu);
List<Student> loadStus();//泛型,List里面只能包含学生,不能包含别的东西了
}
2·在“StudentDaoJDBCImpl”中添加
1)·添加学生的查询语句
private static final String SQL_LOAD_STUS
="select * from tbl_student order by stu_no desc";//倒序,使新增加的学生靠上
2)·书写“loadStus()”
1·pstmt = conn.prepareStatement(SQL_LOAD_STUS);
//没有"?"
rset = pstmt.executeQuery();
//增加删除修改都是update,查询时Query,Query会返回一个结果集,rset里就是记录的存储
2·最终要返回的是对象列表(“public List<Student> loadStus()
”),List<Student> stuList = new ArrayList<>()
;//为对记录进行解析处理,准备容器
3·stu_no等属性名应与数据库的属性名一致
Student stu = new Student();
stu.setStuNo(rset.getInt("stu_no"));
stu.setStuName(rset.getString("stu_name"));
stu.setStuMark(rset.getDouble("stu_mark"));
stuList.add(stu);
完整“loadStus()”如下:
@Override
public List<Student> loadStus() {
Connection conn = DBUtils.getConn();
PreparedStatement pstmt = null;
ResultSet rset = null;//结果集
List<Student> stuList = new ArrayList<>();//为对记录进行解析处理,准备容器
try {
pstmt = conn.prepareStatement(SQL_LOAD_STUS);//没有"?"
rset = pstmt.executeQuery();//增加删除修改都是update,查询时Query,Query会返回一个结果集,rset里就是记录的存储
while(rset.next()){
Student stu = new Student();
stu.setStuNo(rset.getInt("stu_no"));
stu.setStuName(rset.getString("stu_name"));
stu.setStuMark(rset.getDouble("stu_mark"));
stuList.add(stu);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
DBUtils.releaseRes(conn, pstmt, rset);
}
return stuList;
}
三·编写Service层
1·“StudentService”添加List<Student> loadStus();
“StudentService”如下:
/**
*
*/
package edu.mju.stuwork.service;
import java.util.List;
import edu.mju.stuwork.domain.Student;
/**
* @author 20159
*
*/
public interface StudentService {
void regStudent(Student stu);//定义添加学生
List<Student> loadStus();//定义修改学生
}
2·“StudentServiceImpl”添加List<Student> loadStus();
的实现
@Override
public List<Student> loadStus() {
StudentDao stuDao = new StudentDaoJDBCImpl();
return stuDao.loadStus();
}
3·测试(转至Tester下)
StudentService stuService = new StudentServiceImpl();
for(Student stu:stuService.loadStus())//foreach循环,会从集合类型中取一个学生对象给stu
System.out.println(stu);//Student的tuString()已经实现了
Ctrl+Shift+o导入。
完整类如下:
/**
*
*/
package edu.mju.stuwork.test;
import edu.mju.stuwork.domain.Student;
import edu.mju.stuwork.service.StudentService;
import edu.mju.stuwork.service.StudentServiceImpl;
/**
* @author joeyang ong
*
*/
public class Tester {
/**
* @param args
*/
public static void main(String[] args) {
// System.out.println(DBUtils.getConn());
StudentService stuService = new StudentServiceImpl();
for(Student stu:stuService.loadStus())
System.out.println(stu);
}
}
以Java应用程序来运行:
结果如下:
stu_no大的在前。
四·在学生控制器做对应处理,展示给用户
原来的只做学生保存这一件事(收集数据,封装对象,调用stuService()进行对象的存储)现在要对Servlet进行复用(让他再做加载学生列表这件事)。
1·增加识别操作任务的参数
String task = request.getParameter("task");
结构如下:
if(task.equals("createStu")){
//当访问servlet时,如果任务的参数是创建学生,就调用这个部分
}
else if(task.equals("loadStus")){
//否则,如果任务是加载学生列表(loadStus)就进行,这部分。Servlet就实现了复用,通过一个参数,我们可以知道,调用的ServLet的那个部分
}
完整代码如下:
if(task.equals("createStu")){//当访问servlet时,如果任务的参数是创建学生,就调用这个部分
//将学生对象封装起来
Student stu = new Student();
stu.setStuNo(Integer.parseInt(request.getParameter("stuno")));
stu.setStuName(request.getParameter("stuname"));
stu.setStuMark(Double.parseDouble(request.getParameter("stumark")));
// System.out.println(stu);//打印一个对象,就是打印其toString()的返回值
StudentService stuService = new StudentServiceImpl();
stuService.regStudent(stu);
System.out.println("save stu info is ok!");
}
else if(task.equals("loadStus")){//否则,如果任务是加载学生列表(loadStus)就进行,这部分。Servlet就实现了复用,通过一个参数,我们可以知道,调用的ServLet的那个部分
StudentService stuService = new StudentServiceImpl();
List<Student> stuList = stuService.loadStus();
//保存学生信息到请求范围,以便让其他的页面能够分享这些数据。
request.setAttribute("stuList", stuList);//以键值对的方式保存到一定的区域(请求范围)
request.getRequestDispatcher("list_student.jsp").forward(request, response);
}
2·对原先的增加操作做调整,原先的增加操作并没有说明访问的是Servlet的那个功能。
添加隐藏域
,在界面上是看不见的,但是实际上它会发送给服务器。通过这种方式来识别。
<input type="hidden" name="task" value="createStu"/>
添加后如下:
<div class="container">
<h3 class="my-5">新生登记</h3>
<form class="col-6" action="stuMgr" method="post">
<input type="hidden" name="task" value="createStu"/>
<div class="form-group">
<label>学生学号:</label>
<input type="text" class="form-control" name="stuno">
</div>
<div class="form-group">
<label>学生姓名:</label>
<input type="text" class="form-control" name="stuname">
</div>
<div class="form-group">
<label>学生成绩:</label>
<input type="text" class="form-control" name="stumark">
</div>
<button type="submit" class="btn btn-primary">新生登记</button>
</form>
</div>
现在,调用Servlet的loadStus部分,能保存学生信息到请求范围,以便让其他的页面能够分享这些数据。那么需要新建Jsp文件和bootstrap的加入。
五·bootstrap
1·bootstrap准备
将bootstrap的概述和进流程了,在开头看过的话,可以
点击跳转
1)·在“WebContent”下建立文件夹:
vendor:供应商,提供者,第三方库
2)·下载bootstrap:https://getbootstrap.com/
3)·将下载解压后的安装包复制到vendor文件夹下:
4)·添加link(引入样式表)
在图示位置插入link:
复制"css/bootstrap.min.css"的文件路径:
做法:拷贝完全路径:
粘贴到“link”的“href”上:
保留到vendor:
在其前添加应用程序名(绝对路径):
忘记应用程序名的话,如下两张图所示:
5)·容器
使用前:
将的内容用<div class="container"></div>
包起来:
1` <h>的几个样式
1· my-5:margin Y轴,上下外边距,上下保持5个单位的间距,是bootstrap的单位,5是最大
2· mt-5:margin top ,上面保持5个单位的外边距
3· mb-5:margin bottom,下面保持5个单位的外边距:
2` <form>表单的几个样式
1·col-md-6
2·col-12:占满整行,(栅格系统:整行12格
现在运行结果如下:
看起来并没有变化,再进行下面两步。
3`在<form>下的<div>中添加class="form-group"
4`在<form>下的<div>下的<input>中添加class="form-control"
5`以上更改的结果如下:
6`在<button> 中添加 type="submit" class="btn btn-primary"
效果如下:
1·btn:按钮
2·btn-primary:主按钮
3·btn-danger:红色的按钮
4·btn-warning:警告,黄色的按钮
5·btn btn-primary有点大btn btn-primary btn-sm
small小一点
2·调用Servlet的loadStus部分,能保存学生信息到请求范围,以便让其他的页面能够分享这些数据。那么新建Jsp文件。
JSP(Java服务器页面)是网页的变种,在网页上加了一点Java的东西。Html增强版,能够提供动态的内容,动态网页,能根据内存内容的不同,做出不同的界面回应。不同的人访问页面结果不同。
若Jsp的头部含有“ISO-8859-1
”,则修改Jsp的头部为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
meta似乎不影响,但一起修改了:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
3·引入样式表:
<link rel="stylesheet" href="/stuwork/vendor/bootstrap-4.5.3-dist/css/bootstrap.min.css">
在下进行测试:
<button class="btn btn-primary">测试</button>
完整代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="/stuwork/vendor/bootstrap-4.5.3-dist/css/bootstrap.min.css">
<title>Insert title here</title>
</head>
<body>
<button class="btn btn-primary">测试</button>
</body>
</html>
若访问“http://localhost:8080/stuwork/list_student.jsp
”,出现:
则成功。
4·使用bootstrap
来到https://getbootstrap.com/docs/4.5/content/tables/,输入table:
任选,复制一个:
在Jsp中做准备工作,创建“container”的类所修饰的一个
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016082206402.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDAwNzIz,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016082240311.png#pic_center)
然后将复制部分贴入:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016082342697.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDAwNzIz,size_16,color_FFFFFF,t_70#pic_center)
试运行:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016082444623.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDAwNzIz,size_16,color_FFFFFF,t_70#pic_center)
试修改“学生信息列表”的y轴边距:
对复制来的部分按需修改:
测试:
现在将数据库中的数据引用出来,将其写到Jsp页面中
六·java标准标签库(JSTL=Java Standard Tag Library)
1·下载
下载:https://tomcat.apache.org/download-taglibs.cgi
各个jar的区别:https://blog.csdn.net/qq_32115439/article/details/54685786
将下载好的jar贴到该路路径下:
可以看到Web App Libraries 的引用增加了:
任何库在使用前都要引用的过程
2·引入标签库
引入核心库:
再起一个引用上的别名,叫“c”
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
3·编写数据的读取和显示
表头行:
表格行:
如果有多个表格,使用<c:forEach>
,for循环:
<c:forEach items="${stuList}"><!-- for循环 ,把这个范围内的数据取下来 -->
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
</c:forEach>
以"stuList"为Key,将数据取出来,
取下来之后,赋给前面的变量,var=“stu”
<c:forEach var="stu" items="${stuList}">
完整循环如下:
<c:forEach var="stu" items="${stuList}"><!-- for循环 ,把这个范围内的数据取下来 -->
<tr>
<th scope="row">${stu.stuNo}</th>
<td>${stu.stuName}</td>
<td>${stu.stuMark}</td>
</tr>
</c:forEach>
添加操作按钮:
<button class="btn btn-primary btn-sm">修改</button>
<button class="btn btn-danger btn-sm">删除</button>
为了让for循环运行,应该要有数据。在数据存完之后,“StuMgrServlet
”要通知去访问这个页面,页面才知道数据在哪里。
在StuMgrServlet下添加:
request.getRequestDispatcher("list_student.jsp").forward(request, response);
测试:
访问:http://localhost:8080/stuwork/stuMgr?task=loadStus
doGet()是调用doPost()的,所以是可以直接输入网址访问。
?后面是变量名 =是赋值 就是说 传递过去的PTLANG 的值就是 2052 多个变量中间用 &(与)隔开 来进行传递 这个是 GET
传递 就会在地址上出现这样的变量 另一种POST 就不会出现!
引自:https://zhidao.baidu.com/question/1765644448117156060.html
可得:
访问:http://localhost:8080/stuwork/input_student.html
再访问:http://localhost:8080/stuwork/stuMgr?task=loadStus
用户需要自己切换页面,为了让页面在用户键入学生信息保存后,页面自动跳转到学生信息列表页面,添加重定向。
4·添加重定向
//发起一个新的请求,重定向
response.sendRedirect("stuMgr?task=loadStus");
测试:
点击“新生登记”自动跳转:
成功!
第一次比较慢需要编译,第二次就快了。
七·删除
1·调整Dao
1)·StudentDao添加
2)·StudentDaoJDBCImpl添加
添加sql:
private static final String SQL_DEL_STU_BYNO
="delete from tbl_student where stu_no=?";
实现接口:
@Override
public void delStudent(int stuNo) {
Connection conn = DBUtils.getConn();
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(SQL_DEL_STU_BYNO);
pstmt.setInt(1, stuNo);
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
DBUtils.releaseRes(conn, pstmt, null);
}
}
2·调整Service
1)·StudentService添加
void removeStu(int stuNo);
2)·StudentServiceImpl添加
@Override
public void removeStu(int stuNo) {
StudentDao stuDao = new StudentDaoJDBCImpl();
stuDao.delStudent(stuNo);
}
3·调整StuMgrServlet
添加:
代码如下:
else if(task.equals("removeStu")){
//stuMgr?task=removeStu&stuno=123,“?”后是两个参数,参数之间用“&”来间隔
int stuNo = Integer.parseInt(request.getParameter("stuno"));
StudentService stuService = new StudentServiceImpl();
stuService.removeStu(stuNo);
response.sendRedirect("stuMgr?task=loadStus"); //重定向,发起一个新的请求,再次刷新
}
4·模态窗
1)·为了防止误删,添加模态窗,用以用户确认
找一个复制到“list_student”,修改,将“ <div class="" tabindex="-1">”
,的class内容移除,以便能够先在页面中展示模态窗:
<!-- 删除学生信息模态提示窗口 -->
<div class="" tabindex="-1"> <!-- 将class="model"的model拿掉模态窗就可以显示 -->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
结果如下:
下一步,将标题和文字改掉,内容动态生成。
将改回class="model"
,要开启模态窗,还需要准备一个“ID”,没有ID的话找不到它。
现在开启模态窗
不用编程的方法:
在list_student.jsp的删除button添加:
<button class="btn btn-primary btn-sm"
data-toggle="modal" data-target="#removeStuModal">删除</button>
<!-- “data-toggle”说明这个按钮能打开模态窗,打开哪一个由“data-target”加上ID来指定 -->
bootstrap js会查看每一个网页标签中有没有这个属性(指:data-toggle="modal" data-target="#removeStuModal"
),有这些属性的话,它会把代码补充进去。
需要bootstrap的js的参与,引入:
以webroot为根来写,应用程序名是stuwork:
但是bootstrap的js还依赖别的js,它不能够单独工作。
复制:
粘贴到vendor:
加载的规则是别的js先加载。
所以再bootstrap的js之前,添加“jquery”和“popper”
完整“list_student”代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet"
href="/stuwork/vendor/bootstrap-4.5.3-dist/css/bootstrap.min.css">
<script type="text/javascript"
src="/stuwork/vendor/jquery/jquery-3.3.1.js"></script>
<!--模态窗能不能弹出来就靠它了 -->
<script type="text/javascript"
src="/stuwork/vendor/popper.js/popper.min.js"></script>
<script type="text/javascript"
src="/stuwork/vendor/bootstrap-4.5.3-dist/js/bootstrap.min.js"></script>
<title>Insert title here</title>
</head>
<body>
<div class="container">
<h3 class="my-5">学生信息列表</h3>
<table class="table">
<thead>
<tr>
<th scope="col">学号</th>
<th scope="col">姓名</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="stu" items="${stuList}">
<!-- for循环 ,把这个范围内的数据取下来 -->
<tr>
<th scope="row">${stu.stuNo}</th>
<td>${stu.stuName}</td>
<td>${stu.stuMark}</td>
<td>
<button class="btn btn-primary btn-sm">修改</button>
<button class="btn btn-danger btn-sm" data-toggle="modal"
data-target="#removeStuModal">删除</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<!-- 删除学生信息模态提示窗口 -->
<div class="modal" tabindex="-1" id="removeStuModal">
<!-- 将class="modal"的modal拿掉模态窗就可以显示 -->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">操作提示</h5>
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p id="msg">您确认要删除该学生记录吗?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary"
onclick="removeStu();">确认删除</button>
</div>
</div>
</div>
</div>
</body>
</html>
测试:
点击“删除”:
弹出如下模态窗,即为成功:
若有链接错误,到网页右键,查看源代码
将链接的链接都点一遍,如果没有出现类似:
的页面,可能链接书写错误。
模态窗是直接出来的为了实现动画:
2)·模态窗动画
在class处添加fade
3)·模态窗提示内容动态填充
模态窗提示内容根据不同行进行更改
要书写自己的JavaScript
这句话就不能写死了。
以这种方式打开模态窗,功能太固定。
1·使用编程的方式打开:
${stu.stuName}是个字符串‘’加一下
2·查看源码:
参数已在网页自动填充
3·修改
给一个id,“msg”
4·编写JavaScript脚本
内容如下:
<script type="text/javascript">
function showRemoveDlg(stuno, stuname) {
$("#msg").text("您确认要删除学生 [ " + stuname + " ]的信息吗?");/* 使用jquery */
$('#removeStuModal').modal('show');/* 在bootstrap的网页上有说明如何用编程来开启模态窗,复制黏贴 */
}
</script>
测试:
4)·最后的删除操作
在
这个按钮上绑定事件
1·修改按钮
2·编JavaScript脚本
修改前面的脚本,可得:
<script type="text/javascript">
var stuNo;/* 建立全局变量,使“removeStu()”可以使用“showRemoveDlg(stuno, stuname)” */
function showRemoveDlg(stuno, stuname) {
stuNo = stuno;/* 将变量预存到外面的全局变量上 */
$("#msg").text("您确认要删除学生 [ " + stuname + " ]的信息吗?");/* 使用jquery */
$('#removeStuModal').modal('show');/* 在bootstrap的网页上有说明如何用编程来开启模态窗,复制黏贴 */
}
function removeStu() {
location.href = "/stuwork/stuMgr?task=removeStu&stuno=" + stuNo;/* location是地址栏,href是地址栏上面的文字,location.href即修改地址栏上面的文字。到这个网址 就实现了删除*/
/* location.href='<c:url value="/stuMgr" />?task=preUpdate&stuno='+stuNo; 效果与上行相同或类似*/
}
</script>
测试:
点击“确认删除”后学生信息消失:
成功!