一·欢迎页面
当直接以应用程序名访问时:
为了不看到(出现)这个404:
1·新建Jsp——index.jsp
新建index.jsp作为欢迎界面。
查看web.xml(web 应用程序的配置文件)
列出了一些欢迎文件列表。当访问Web应用程序,但是没有说明访问的是Web应用程序的哪个部分时,会使用欢迎文件来作为默认的显示页面。六个欢迎文件是从上往下适配的。上面的文件找到了下面的文件就不找了。如果六个都没找到就显示404。
试直接访问“http://localhost:8080/stuwork/”:
2·对index.jsp进行处理
添加:
<jsp:forward page="stuMgr?task=loadStus"></jsp:forward>
作用:一旦访问index.jsp,就会自动跳转到"stuMgr?task=loadStus"
完整index.jsp如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<jsp:forward page="stuMgr?task=loadStus"></jsp:forward>
</body>
</html>
一旦访问index.jsp就会跳转到"stuMgr?task=loadStus"
:
可以看出,访问的是index.jsp。因为在查找文件时:
这两个文件找不到,就访问第三个。
所以,用户在访问应用程序名时,显示的学生信息列表。
还可以指定默认应用程序。
二·MVC设计模式(Model View Controller)
设计模式:前人总结的行之有效的方法。
View(视图):和用户见面的,.html,.jsp
Model(模型):service(业务模型),domain(实体模型)
controller(控制器):servlet(在此做交通控制)
知道你要干嘛,帮助收集数据,叫人干活,把结果叫另一个jsp显示
MVC设计模式认为:我们的网址上不能直接出现视图,所有的视图必须被控制起来,不能让用户直接访问。网址上只能出现控制器的访问的路径,用户只能访问控制器,由控制器来决定应用什么视图来做回应,
1·在WEB-INF下建立文件夹“views”
将除了欢迎页面以外的所有视图搬到“views”中:
直接访问:
WEB-INF是一个安全目录,用户直接访问是不行的。得到的是404。
在stuMgrServlet添加:
在WEB-INF的文件直接访问时不行的,但是通过这种间接访问是可以的。通过访问Servlet,Servlet帮助转到这个页面。
用的是相对路径,因为Servlet就是根路径了:
WEB-INF在WebContent下,WebContent就是根路径了。
同步修改下面的路径:
测试:
以“http://localhost:8080/stuwork/stuMgr?task=toInput”
访问:
以“http://localhost:8080/stuwork/”
访问:
写的是toInput".equals(task)
”而不是task.equals("toInput")
,当task是空的时候防止空指针异常。
不能让用户输入网址来修改:
在页面上增加按钮:
在list_student.jsp添加,修改:
<h3 class="my-5 mb-3">学生信息列表</h3><!-- 调整与按钮的上下关系 -->
<div class="my-2 text-right"><!-- 将按钮移到右边 --><!-- 给按钮增加一个行的容器 -->
<button class="btn btn-primary" onclick="location.href='stuMgr?task=toInput'">新生注册</button>
</div>
测试:
点击按钮成功跳转:
三·在页面修改
不能让用户在:
一片白上修改。点击修改时,要读取学生信息填入,一些信息是可以修改的,有一些信息是不可以修改的,比如学号。要更改学号,只能删除再增加。
1·根据学生ID来获得一个学生信息
1)·修改StudentDao
添加:
Student getStuByNo(int stuNo);//根据学生ID来获得一个学生信息
2)·修改StudentDaoJDBCImpl
添加sql:
private static final String SQL_GET_STU_BYNO
= "select * from tbl_student where stu_no=?";
实现:
@Override
public Student getStuByNo(int stuNo) {
//三种接口对象
Connection conn = DBUtils.getConn();
PreparedStatement pstmt = null;
ResultSet rset = null;//结果集
Student stu = null;
try {
pstmt = conn.prepareStatement(SQL_GET_STU_BYNO);
pstmt.setInt(1, stuNo);
rset = pstmt.executeQuery();
//是根据主键来查的,要么有一条,要么没有,结果是“找到”或“找不到”,就不用“while”了,用“if”就好
if(rset.next()){
stu = new Student();//创建一个空白的学生对象,来收集数据
stu.setStuNo(rset.getInt("stu_no"));//属性根据数据库
stu.setStuName(rset.getString("stu_name"));
stu.setStuMark(rset.getDouble("stu_mark"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DBUtils.releaseRes(conn, pstmt, rset);
}
return stu;
}
3)·修改StudentService
添加:
Student getStuByNo(int stuNo);
4)·修改StudentServiceImpl
添加:
public Student getStuByNo(int stuNo) {
StudentDao stuDao = new StudentDaoJDBCImpl();
return stuDao.getStuByNo(stuNo);
}
5)·测试
转到“Tester”
StudentService stuService = new StudentServiceImpl();
System.out.println(stuService.getStuByNo(125));//看看能不能拿到125号学生的信息
Tester.java右键->Run As->Java Application:
成功!
2·显示
1)·复制input_student.html改名为update_student.jsp
修改头部:
<%@ 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 charset="UTF-8">
<link rel="stylesheet" href="/stuwork/vendor/bootstrap-4.5.3-dist/css/bootstrap.min.css">
<title>Insert title here</title>
</head>
2)·修改Servlet
添加:
else if("preUpdate".equals(task)){//更新前的动作
//stuMgr?task=preUpdate&stuno=123
int stuNo = Integer.parseInt(request.getParameter("stuno"));
StudentService stuService = new StudentServiceImpl();
Student stu = stuService.getStuByNo(stuNo);
// 将数据回填到updata_student.jsp
// 把数据库取出的数据回填到表单之中
// 保存数据到请求范围,以便jsp能够分享到这些数据
request.setAttribute("stu", stu);
// 通知jsp,只要访问Servlet的这个部分数据就会回填到update_student.jsp
request.getRequestDispatcher("WEB-INF/views/update_student.jsp").forward(request, response);
}
3)·完善update_student.jsp
完整的update_student.jsp如下:
<%@ 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 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="updateStu"/>
<input type="hidden" name="stuno" value="${stu.stuNo}"/>
<div class="form-group">
<label>学生学号:${stu.stuNo}</label><!-- 学号是不可修改的 -->
</div>
<div class="form-group">
<label>学生姓名:</label>
<input type="text" class="form-control" name="stuname" value="${stu.stuName}"><!-- 用EL表达式来回填的 EL表达式:Expression Language-->
</div>
<div class="form-group">
<label>学生成绩:</label>
<input type="text" class="form-control" name="stumark" value="${stu.stuMark}">
</div>
<button type="submit" class="btn btn-primary">信息修改</button>
</form>
</div>
</body>
</html>
测试:
以http://localhost:8080/stuwork/stuMgr?task=preUpdate&stuno=1234
访问:
跳转到:
OK!
学生学号是文字的形式,表名是不能改的。
为了让用户不再输入网址访问,制作按钮,点击“修改”按钮。
且为了方便用户使用不切换窗口的方式,修改数据
4)·在list_student.jsp添加function:
function updateStu(stuNo){/* 传入学生学号 */
location.href="/stuwork/stuMgr?task=preUpdate&stuno="+stuNo;
}
对“修改”按钮添加参数“onclick”:
<button class="btn btn-primary btn-sm"
onclick="updateStu(${stu.stuNo})">修改</button>
3·测试:来到网页查看源代码:
已经有了改变。
4·修改学生信息
1)·修改StudentDao
void updateStudent(Student stu);
2)·修改StudentDaoJDBCImpl
添加sql:
private static final String SQL_UPDATE_STU
="update tbl_student set stu_name=?,stu_mark=? where stu_no=?";//不判断哪个属性有改哪个属性没改,没改的就拿原来的数据回填,是全字段更新,节省数据库的开支,主键不能改
实现接口:
@Override
public void updateStudent(Student stu) {//拿增加来修改,因为增加也要设置每个属性
Connection conn = DBUtils.getConn();
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(SQL_UPDATE_STU);
pstmt.setString(1, stu.getStuName());
pstmt.setDouble(2, stu.getStuMark());
pstmt.setInt(3, stu.getStuNo());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally{
DBUtils.releaseRes(conn, pstmt, null);
}
}
3)·修改StudentService
添加:
void updateStudent(Student stu);
4)·修改StudentServiceImpl
添加:
@Override
public void updateStudent(Student stu) {
StudentDao stuDao = new StudentDaoJDBCImpl();
stuDao.updateStudent(stu);
}
5)·修改Servlet
添加:
else if("updateStu".equals(task)){
int stuNo = Integer.parseInt(request.getParameter("stuno"));
String stuName = request.getParameter("stuname");
double stuMark = Double.parseDouble(request.getParameter("stumark"));
Student stu = new Student();
stu.setStuNo(stuNo);
stu.setStuName(stuName);
stu.setStuMark(stuMark);
StudentService stuService = new StudentServiceImpl();
stuService.updateStudent(stu);
response.sendRedirect("stuMgr?task=loadStus");
}
6)·修改update_student.jsp
结果如下:
<%@ 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 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="updateStu"/>
<!-- 学生学号也要传上去,单数不能出现在界面上,所以添加隐含域 -->
<input type="hidden" name="stuno" value="${stu.stuNo}"/>
<div class="form-group">
<label>学生学号:${stu.stuNo}</label><!-- 学号是不可修改的 -->
</div>
<div class="form-group">
<label>学生姓名:</label>
<input type="text" class="form-control" name="stuname" value="${stu.stuName}"><!-- 用EL表达式来回填的 -->
</div>
<div class="form-group">
<label>学生成绩:</label>
<input type="text" class="form-control" name="stumark" value="${stu.stuMark}">
</div>
<button type="submit" class="btn btn-primary">信息修改</button>
</form>
</div>
</body>
</html>
7)·回到Servlet的updateStu部分
添加重定向:
response.sendRedirect("stuMgr?task=loadStus");
8)·测试
重定向回来页面已修改:
四·在模态窗修改(单页面应用程序)
1·修改list_student.jsp
编写脚本:
function regStu(){
document.forms['stuFrm'].submit();/* 提交表单 */
$('#regStuModal').modal('hide');/* 关闭模态窗 */
}
添加模态窗:
<!-- 新生注册注册模态窗口 -->
<div class="modal fade" tabindex="-1" id="regStuModal">
<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">
<form name="stuFrm" action="<c:url value="/stuMgr"/>"
class="col-12" 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>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="regStu()">新生注册</button>
</div>
</div>
</div>
</div>
修改原有按钮:
为:
<button class="btn btn-primary mb-2"
data-toggle="modal" data-target="#regStuModal">新生登记</button>
<!-- 不编程的方式打开模态窗,但是要加载Bootstrap的js文件 -->
“新增”模态窗不需要显示原有信息,所以可以使用不编程的方式来编程。
测试:
点击:“新生注册”:
在模态窗点击“取消”也会自动关闭模态窗:
成功!