C02_D02_UrlRewriting

讯享网
index.html
<!DOCTYPE html>
<html>
<head>
<title>会话管理技术->URL重写(URL Rewriting)</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
<h1 class="text-center text-primary">会话管理技术->URL重写(URL Rewriting)</h1>
<hr>
<br>
<form action="profile.jsp" class="form-inline">
<label for="xuehao">学号: </label>
<input type="text" name="rollno" id="xuehao" class="form-control">
<input type="submit" value="查询个人信息" class="btn btn-sm btn-primary">
</form>
</div>
</body>
</html>
讯享网

点击查询个人信息后:

点击查看个人成绩单后:

C02_D03_Cookie


login.jsp
讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录首页</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<!--Cookie: 是Web程序创建放到客户端的小型文本文件,用于存储少量的用户信息-->
<!--Cookie由服务器端创建,和响应一起发送到客户端,存放在客户端的小型文本文件-->
<div class="container">
<form action="ls" class="form-inline text-center loginForm bg-primary">
<h1 class="text-center">用户登录</h1>
<hr>
<br>
账 号: <input type="text" name="username" class="form-control">
<br><br>
密 码: <input type="password" name="password" class="form-control">
<br><br>
<input type="submit" value="登录" class="btn btn-sm btn-default">
</form>
</div>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
<title>登录失败页面</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<br>
<h1 class="msg-warning">
<!--点击超链接可以执行javascript代码,javascript提供对象history-->
<!--history对象的back()函数实现退回上一个页面,也就是返回的效果-->
<!--如果点击超链接想执行javascript,直接在href中编写javascript:js代码即可-->
账户或密码错误,请<a href="javascript:history.back();">返回</a>重新登录!
</h1>
<hr>
</body>
</html>

讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录成功</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<h1 class="text-center text-success">登录成功,XXX,欢迎进入教务系统</h1>
<a href="#" class="logout">退出登录</a>
<hr><br>
<ul class="list-menu">
<li><a href="profile.jsp">查看个人信息</a></li>
</ul>
</div>
</body>
</html>
LoginServlet
package com.qdu.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ls")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uname = req.getParameter("username");
String pwd = req.getParameter("password");
//这里设定用户名是anna,密码是1234,则登录成功
if ("anna".equals(uname) && "1234".equals(pwd)) {
//HttpServletResponse的sendRedirect()实现重定向
//也就是重定向到另一个页面作为响应内容
resp.sendRedirect("success.jsp");
} else {
resp.sendRedirect("fail.html");
}
}
}
C02_D03_Cookie

login.jsp
讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录首页</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
<style>
label:hover{
cursor: pointer;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<br>
<p class="text-danger">
* 本程序没有连接数据库,使用账户anna和密码1234可以通过登录验证 <br>
* 本程序使用Cookie实现记住用户密码的功能
</p>
<%
//JSP提供隐式对象request,表示该页面收到的请求
//通过请求对象可以获取到该程序放的所有Cookie,以Cookie数组的形式返回
Cookie[] cks=request.getCookies();
//也可能一个Cookie都没有,则无需遍历Cookie数组,直接返回
if(null==cks) return;
//定义两个变量,用于存储Cookie的值
String uname="";
String upwd="";
//如果有Cookie,则遍历Cookie数组,读取Cookie的值即可
for(Cookie c:cks){ //对于数组cks中的每个Cookie对象
//如果当前遍历的cookie的名称是username
if("username".equals(c.getName()))
uname=c.getValue(); //获取其值,存储到变量uname中
else if("userpwd".equals(c.getName())) //如果当前遍历的cookie的名称是userpwd
upwd=c.getValue(); //获取其值,存储到变量upwd中
}
%>
<!--
这里将两个文本框的值分别设置为两个Cookie的值
如果有对应的Cookie值,则会显示在文本框中
如果没有对应的Cookie值,则显示空白,也就是记住密码的功能
-->
<form action="ls" class="form-inline text-center loginForm bg-primary">
<h1 class="text-center">用户登录</h1>
<hr>
<br>
账 号: <input type="text" name="username" value="<%=uname%>" class="form-control">
<br><br>
密 码: <input type="password" name="password" value="<%=upwd%>" class="form-control">
<br><br>
<input type="checkbox" id="remember" name="rem" value="Y">
<label for="remember">记住密码</label>
<input type="submit" value="登录" class="btn btn-sm btn-default">
</form>
</div>
</body>
</html>

web.html
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<!--welcome-file-list标记用于定义程序的欢迎文件列表-->
<!--欢迎文件可以设置多个,如果前面的页面不可用,则会使用后面的页面-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
<!-- <welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>home.html</welcome-file>
<welcome-file>home.jsp</welcome-file>-->
</welcome-file-list>
</web-app>

LoginServlet
讯享网package com.qdu.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ls")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uname = req.getParameter("username");
String pwd = req.getParameter("password");
//创建Cookie,用于存储少量的用户信息
//Cookie是一种客户端技术,用于存储少量的用户信息
//Cookie是服务器端创建,发送到客户端,存储在客户端的小型文本文件
//使用Cookie类创建和操作Cookie
//Cookie是以键-值对的形式存储数据,键和值都是字符串
//一个Cookie只能用于存储一项信息
//默认情况下Cookie是浏览器会话范围的cookie,随着浏览器关闭,Cookie会立刻被删除
Cookie ck1 = new Cookie("username", uname);
Cookie ck2 = new Cookie("userpwd", pwd);
String rem = req.getParameter("rem");
//可以设置Cookie的最大时间,也就是Cookie存在客户端多久,单位是秒
//如果设置了最大时间,则在到期前,即使关闭浏览器再打开,Cookie依然会存在
if ("Y".equals(rem)) { //如果用户选择记住密码,则设置Cookie 存在7天
ck1.setMaxAge(7 * 24 * 60 * 60);
ck2.setMaxAge(7 * 24 * 60 * 60);
}else{ //否则立刻删除Cookie
//考虑到用户可能上次记住,存储了cookie,这次选择不记住,则该种情况下要删除Cookie
//Cookie类没有提供专门的方法用于删除一个Cookie
ck1.setMaxAge(0); //最大时间为0意味着立刻删除Cookie
ck2.setMaxAge(0);
}
//Cookie需要存储到客户端,所以需要和响应一起发送到客户端并存储在客户端
//只不过是作为响应的报头/标头发送给客户端的
//必须在设置好Cookie之后,将Cookie添加到响应对象中,才能发送到客户端
resp.addCookie(ck1);
resp.addCookie(ck2);
if ("anna".equals(uname) && "1234".equals(pwd)) {
//HttpServletResponse的sendRedirect()方法用于重定向到指定页面作为响应内容
resp.sendRedirect("success.jsp"); //succeed
} else {
resp.sendRedirect("fail.html");
}
}
}
success.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录成功</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<!--Cookie是服务器端创建,发送到客户端的小型文本文件,用于存储少量的用户信息-->
<!--一旦Cookie保存在客户端,后续再次请求该程序的任何资源,Cookie会随着请求-->
<!--一起被发送返回给服务器,这样服务器端可以读取Cookie的信息-->
<%
//JSP提供隐式对象request,表示该页面收到的请求
//通过请求对象可以获取到该程序放的所有Cookie,以Cookie数组的形式返回
Cookie[] cks=request.getCookies();
//也可能一个Cookie都没有,则无需遍历Cookie数组,直接返回
if(null==cks) return;
//定义两个变量,用于存储Cookie的值
String uname="";
String upwd="";
//如果有Cookie,则遍历Cookie数组,读取Cookie的值即可
for(Cookie c:cks){ //对于数组cks中的每个Cookie对象
//如果当前遍历的cookie的名称是username
if("username".equals(c.getName()))
uname=c.getValue(); //获取其值,存储到变量uname中
else if("userpwd".equals(c.getName())) //如果当前遍历的cookie的名称是userpwd
upwd=c.getValue(); //获取其值,存储到变量upwd中
}
%>
<br>用户:<%=uname%>
<br>密码:<%=upwd%>
<h1 class="text-center text-success">登录成功,<%=uname%>,欢迎进入教务系统</h1>
<a href="#" class="logout">退出登录</a>
<hr>
<br>
<a href="profile.jsp">查看个人信息</a>
</div>
</body>
</html>

profile.jsp
讯享网
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>个人信息</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
<h1 class="text-center text-warning">个人信息</h1>
<hr>
<br>
<%
//JSP提供隐式对象request,表示该页面收到的请求
//通过请求对象可以获取到该程序放的所有Cookie,以Cookie数组的形式返回
Cookie[] cks=request.getCookies();
//也可能一个Cookie都没有,则无需遍历Cookie数组,直接返回
if(null==cks) return;
//定义两个变量,用于存储Cookie的值
String uname="";
String upwd="";
//如果有Cookie,则遍历Cookie数组,读取Cookie的值即可
for(Cookie c:cks){ //对于数组cks中的每个Cookie对象
//如果当前遍历的cookie的名称是username
if("username".equals(c.getName()))
uname=c.getValue(); //获取其值,存储到变量uname中
else if("userpwd".equals(c.getName())) //如果当前遍历的cookie的名称是userpwd
upwd=c.getValue(); //获取其值,存储到变量upwd中
}
%>
<br>用户:<%=uname%>
<br>密码:<%=upwd%>
</div>
</body>
</html>
C02_D04_Session


index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录首页</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<form action="ls" class="form-inline text-center loginForm bg-cyan">
<h1 class="text-center">用户登录</h1>
<hr>
<br>
学 号: <input type="text" name="rollno" class="form-control">
<br><br>
密 码: <input type="password" name="pwd" class="form-control">
<br><br>
<input type="submit" value="登录" class="btn btn-sm btn-default">
</form>
</div>
</body>
</html>
success.jsp
讯享网<%@page import="com.qdu.pojo.Student"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录成功</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<h1 class="text-center text-success">欢迎进入教务系统</h1>
<%
//根据属性名获取会话中的属性值
//如果需要转换到对应类型,需要强制转换
Student s=(Student)session.getAttribute("student");
%>
<a href="#" class="info">当前登录:<%=s.getSname() %> </a>
<a href="los" class="logout">退出登录</a>
<hr><br>
<!--jsp提供隐式对象session,用于在jsp页面**问当前的会话对象-->
<ul class="list-menu">
<li><a href="profile.jsp">查看个人信息</a></li>
<li><a href="#">查询班级课表</a></li>
<li><a href="#">查看个人成绩</a></li>
</ul>
</div>
</body>


profile.jsp
<%@page import="com.qdu.pojo.Student"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>个人信息</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<h1 class="text-center text-warning">个人信息</h1>
<hr>
<br>
<div class="content-container">
<%
//放入会话的数据可以在程序中的任何jsp页面或servlet中获取到
//因为只要会话没有结束,则数据会一直存在于会话中,除非手动清除
Student stu=(Student)session.getAttribute("student");
%>
<br>学号: <%=stu.getSrollno() %>
<br>姓名: <%=stu.getSname()%>
<br>性别: <%=stu.getSgender()%>
<br>密码: <%=stu.getSpassword()%>
<br>班级: <%=stu.getSbatch()%>
<br>
<!--title用于指定鼠标悬到图片上的提示文字-->
<!--alt用于指定图片无法正常显示的时候的替代文字-->
<img class="photo" width="150" height="150"
src="images/<%=stu.getSrollno()%>.jpg"
alt="<%=stu.getSname()%>"
title="<%=stu.getSname()%>">
</div>
</div>
</body>
</html>
DatabaseUtil
讯享网package com.qdu.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; / * 数据库工具类,帮助获取到对应数据库的连接和关闭连接 * * @author Anna */ public class DatabaseUtil { private static final String DRIVER_CLASS="com.microsoft.sqlserver.jdbc.SQLServerDriver"; private static final String URL="jdbc:sqlserver://localhost:1433;databaseName=QDU"; private static final String USERNAME = "sa"; private static final String PASSWORD = "sa"; / * 获取数据库连接 * * @return 一个数据库连接对象 */ public static Connection getConnection() { try { Class.forName(DRIVER_CLASS); return DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (Exception ex) { ex.printStackTrace(); } return null; } / * 关闭数据库连接 * * @param rs 结果集对象 * @param ps 语句对象 * @param con 连接对象 */ public static void close(ResultSet rs, PreparedStatement ps, Connection con) { try { if (null != rs) { rs.close(); } if (null != ps) { ps.close(); } if (null != con) { con.close(); } } catch (Exception ex) { ex.printStackTrace(); } } }
LoginServlet
package com.qdu.servlet;
import com.qdu.dao.StudentDao;
import com.qdu.pojo.Student;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/ls")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String rollno = req.getParameter("rollno");
String pwd = req.getParameter("pwd");
StudentDao dao=new StudentDao();
Student stu=dao.findStudentByRollno(rollno);
//如果stu不为null,说明学号正确,只需要再判断密码即可
if (null!=stu&&pwd.equals(stu.getSpassword())) {
//会话技术就是为每一个浏览器用户分配一个HttpSession对象
//用于在会话期间维护一些用户数据
//getSession()获取和请求关联的会话对象,如果还没有会话对象,则创建一个新的会话对象
//getSession(false)获取和请求关联的会话对象,如果还没有会话,返回null
//HttpSession session=req.getSession(false);
HttpSession session=req.getSession();
//你可以将在会话期间共享的数据作为属性(attribute)放入会话对象
//一个属性由一个属性名和一个属性值构成,后续使用的时候通过属性名获取属性值
//属性名必须是字符串,属性的值可以是任何对象,如一个字符串,一个学生对象等
session.setAttribute("student",stu);
//session.setAttribute("number", 10);
resp.sendRedirect("success.jsp");
} else {
resp.sendRedirect("fail.html");
}
}
}
Student.java
讯享网package com.qdu.pojo; / * 学生实体类,用于存储学生所有信息 * * @author NIIT */ public class Student { private String srollno; private String sname; private String sgender; private String sbatch; private String spassword; public Student() { } public Student(String srollno, String sname, String spassword, String sgender, String sbatch) { this.srollno = srollno; this.sname = sname; this.sgender = sgender; this.sbatch = sbatch; this.spassword = spassword; } public String getSrollno() { return srollno; } public void setSrollno(String srollno) { this.srollno = srollno; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public String getSgender() { return sgender; } public void setSgender(String sgender) { this.sgender = sgender; } public String getSbatch() { return sbatch; } public void setSbatch(String sbatch) { this.sbatch = sbatch; } public String getSpassword() { return spassword; } public void setSpassword(String spassword) { this.spassword = spassword; } }
StudentDao.java
package com.qdu.dao; import com.qdu.pojo.Student; import com.qdu.util.DatabaseUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; / * Dao类-数据访问对象类,专门用于访问数据库中的表 <br> * StudentDao包含方法用于对StudentMark表执行增删改查, 这里只封装了一个方法用于查询 * * @author Anna */ public class StudentDao { / * 根据学号查询学生所有信息 * * @param rollno 学生学号 * @return 包含学生所有信息的学生对象 */ public Student findStudentByRollno(String rollno) { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = DatabaseUtil.getConnection(); ps = con.prepareStatement("select * from student where Srollno=?"); ps.setString(1, rollno); rs = ps.executeQuery(); if (rs.next()) { return new Student(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5)); } } catch (Exception e) { e.printStackTrace(); } finally { DatabaseUtil.close(rs, ps, con); } return null; } }
LogoutServlet
讯享网package com.qdu.servlet;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/los")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//getSession(false)获取已有的会话对象,如果还没有会话对象,则返回null
HttpSession session = req.getSession(false);
if (null != session) {//如果会话不为null
session.invalidate(); //调用invalidate()使会话无效,也就是立刻结束会话
resp.sendRedirect("index.html"); //退出登录后回到首页
//session.setMaxInactiveInterval(10*60); 单位是秒
}
}
}
C02_D06_SessionExercise


index.html
<!DOCTYPE html>
<html>
<head>
<title>天猫首页</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="images/shortcut.png" rel="shortcut icon" type="image/x-icon"/>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<div class="top">
<div class="top_left"><img src="images/tmall.png" alt="天猫logo"></div>
<div class="top_right"><h1>欢迎来到天猫,理想生活上天猫......</h1></div>
</div>
<hr>
<h3>最新活动</h3>
<br>
<ul>
<!--可以通过url重写追加请求参数,体现是不同的产品-->
<li><a href="ps?pid=P001">卫龙辣条,你值得拥有</a></li>
<li><a href="ps?pid=P002">青岛大虾,不一样的大虾</a></li>
<li><a href="ps?pid=P003">四级真题,600包过</a></li>
<li><a href="ps?pid=P004">快乐肥宅水,你今天快乐了吗?</a></li>
</ul>
<br>
<a href="cart.jsp">查看购物车</a>
</div>
</body>
</html>
style.css
讯享网 .top{ height: 120px; } .top_left{ width: 20%; float:left; } .top_right{ width: 80%; float:left; } .top_right h1{ height: 100px; line-height: 100px; margin-left:50px; color: darkred; } .content{ position: relative; padding-left: 300px; width: 700px; margin: 30px auto; } .pic{ position: absolute; top: 20px; left: 0px; width: 250px; height: 250px; } .viewcart{ position: fixed; top: 30px; right: 30px; } .title{ color: brown; text-align: center; } form .form-control{ width: 60px!important; } .cartProduct{ position: relative; } .cartProduct img{ position: absolute; top: 11px; left: 200px; border-radius: 100px; border: solid lightgray 1px; } ul{ line-height: 30px; }
ProductDao.java
package com.tianmao.dao; import com.tianmao.util.DatabaseUtil; import com.tianmao.entity.Product; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; / * Dao类-数据访问对象类,专门用于访问数据库中的表ProductDao包含方法用于对Product表执行增删改查 * @author Anna */ public class ProductDao { / * 查询所有产品的列表 * @return 产品列表 */ public List<Product> getProductList() { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; List<Product> productList=new ArrayList(); try { con = DatabaseUtil.getConnection(); ps = con.prepareStatement("select * from Product"); rs = ps.executeQuery(); while (rs.next()) { productList.add(new Product(rs.getString(1),rs.getString(2),rs.getFloat(3),rs.getString(4),rs.getInt(5))); } return productList; } catch (Exception e) { e.printStackTrace(); } finally{ DatabaseUtil.close(rs,ps,con); } return null; } / * 根据产品编号查询产品信息 * @param productId 字符串表示的产品编号 * @return 包含产品所有信息的一个Product对象,如果没有查询到该产品,则返回null */ public Product findProductById(String productId) { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = DatabaseUtil.getConnection(); ps = con.prepareStatement("select * from Product where productId=?"); ps.setString(1, productId); rs = ps.executeQuery(); if (rs.next()) { return new Product(rs.getString(1),rs.getString(2),rs.getFloat(3),rs.getString(4),rs.getInt(5)); } } catch (Exception e) { e.printStackTrace(); } finally{ DatabaseUtil.close(rs,ps,con); } return null; } }
ProductServlet
讯享网package com.tianmao.servlet; import com.tianmao.dao.ProductDao; import com.tianmao.entity.Product; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; / * 该Servlet处理根据产品编号查询产品的请求,然后将查询出来的产品信息交给productInfo.jsp显示 * * @author Anna */ @WebServlet("/ps") public class ProductServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 获取请求参数 String pid=req.getParameter("pid"); //2. 执行业务逻辑,完成请求处理 ProductDao dao=new ProductDao(); Product pro=dao.findProductById(pid); //根据产品编号查询单个产品的所有信息 //3. 将查询到的信息共享给productInfo.jsp页面显示 //如果希望将一些信息共享到下个servlet或jsp,而不是通过会话共享 //则可以考虑将信息作为属性添加到请求对象,然后转发请求 //可以将产品对象作为一个属性放入请求对象,这里属性名是product req.setAttribute("product", pro); //将同一个请求对象和响应对象转发给productInfo.jsp //这样productInfo.jsp收到的请求是同一个请求,所以可以获取到共享的数据 //forward转发 req.getRequestDispatcher("/productInfo.jsp").forward(req, resp); } }
productInfo.jsp
<%@page import="com.tianmao.entity.Product"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="images/shortcut.png" rel="shortcut icon" type="image/x-icon"/>
<title>产品信息</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<h1 class="text-center text-primary">产品信息</h1>
<hr>
<br>
<!--在此div中显示从数据库查询到的一个产品的所有信息-->
<%
//因为ps这个servlet转发了请求给productInfo.jsp
//所以productInfo.jsp收到的请求就是ps收到的请求,两个处理的是同一个请求
Product p=(Product)request.getAttribute("product");
%>
<div class="content">
<br>
<!--显示产品图片,图片在images文件夹中给出了,以产品的编号命名的图片-->
<img src="images/<%=p.getProductId()%>.jpg" class="pic">
<h3>产品名称: <%=p.getProductName() %> </h3>
<p>产品单价: <%=p.getProductPrice()%> </p>
<p>包装单位: <%=p.getProductUnit()%> </p>
<p>剩余库存: <%=p.getProductQty()%> </p>
<!--提交请求给cs,添加产品到购物车 shopping cart-->
<form action="cs" class="form-inline">
<b>购买数量:</b>
<input type="number" min="1" name="qty" value="1" class="form-control">
<br><br>
<!--在表单中,如果有些数据需要隐式地提交,则可以使用隐藏字段-->
<input type="hidden" name="pid" value="<%=p.getProductId()%>">
<!--为了简化程序,后续不再次查询数据库,我们考虑将产品的其他信息一起提交-->
<input type="hidden" name="pname" value="<%=p.getProductName() %>">
<input type="hidden" name="pprice" value="<%=p.getProductPrice() %>">
<input type="hidden" name="punit" value="<%=p.getProductUnit() %>">
<input type="submit" value="加入购物车" class="btn btn-sm btn-danger">
<input type="submit" value="立刻购买" class="btn btn-sm btn-warning">
</form>
</div>
<br>
<a href="cart.jsp" class="viewcart">查看购物车</a>
</body>
</html>
CartServlet
讯享网package com.tianmao.servlet; import com.tianmao.entity.Product; import java.awt.event.ActionListener; import java.io.IOException; import java.util.ArrayList; import java.util.List; 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 javax.servlet.http.HttpSession; import javax.swing.JButton; / * 点击“加入购物车”按钮,添加产品到购物车,该Servlet负责处理添加到购物车的请求 * * @author Anna */ @WebServlet("/cs") public class CartServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 获取请求参数 String pid = req.getParameter("pid"); //Ctrl+Shift+上/下 String pname = req.getParameter("pname"); //byte,short,int,long,float,double,char,boolean //Byte,Short,Integer,Long,Float,Double,Character,Boolean float pprice = Float.parseFloat(req.getParameter("pprice")); String punit = req.getParameter("punit"); int qty = Integer.parseInt(req.getParameter("qty")); //为了更方便的操作产品的5项信息,可考虑将其封装成一个产品对象 //但是这里的数量表示的不是库存量,而是加入购物车的数量 Product p = new Product(pid, pname, pprice, punit, qty); //可以考虑维护一个Product列表,用于存储购物车中所有产品的信息 //添加一个产品到购物车,也就是添加一个产品对象到该列表中 List<Product> list=null; //定义一个变量,表示购物车列表 HttpSession session=req.getSession(); //获取会话对象 //如果会话中已经有了cartList属性,说明不是第一次添加产品到购物车 //否则说明是第一次添加产品到购物车 if(null!=session.getAttribute("cartList")){ //如果已经有列表,获取该购物车列表,赋值给变量list //因为实际放入的是一个List<Product>类型,所以可以强制转换类型 list=(List<Product>)session.getAttribute("cartList"); list.add(p); //添加本次的产品到购物车列表 }else{ //第一次添加产品到购物车 list=new ArrayList(); //创建购物车列表 list.add(p); //添加第一个产品到购物车列表 //为了让购物车列表在会话期间可访问,可将购物车列表添加到会话中 session.setAttribute("cartList",list); //将购物车列表作为一个属性添加到会话对象 } //因为列表是在会话中,不是在请求对象中,所以直接重定向到cart.jsp页面显示购物车列表即可 resp.sendRedirect("cart.jsp"); } }
cart.jsp
<%@page import="java.util.List"%>
<%@page import="com.tianmao.entity.Product"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="images/shortcut.png" rel="shortcut icon" type="image/x-icon"/>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
<title>购物车信息</title>
</head>
<body>
<div class="container">
<h1 class="text-center text-danger">购物车信息</h1>
<!--这里给出了购物车中一个产品的显示格式-->
<%
//根据属性名cartList获取属性值,值是一个List<Product>对象
List<Product> clist=(List)session.getAttribute("cartList");
if(null==clist){
out.println("<br><h1>尚未添加任何产品到购物车!!!</h1>");
return; //如果没有产品,无需遍历,直接返回即可,这样后面的代码都不会执行
}
//如果购物车中有产品,则执行后续代码,遍历列表
float total=0; //定义一个变量,用于存储总计金额
for(Product p:clist){ //对于集合clist中的每个产品
total+=p.getProductPrice() * p.getProductQty(); //总计金额每次在原来的基础上加上当前产品的小计金额
%>
<div class="cartProduct">
<img src="images/<%=p.getProductId()%>.jpg" width="120" height="120">
<hr>
产品名称:<%=p.getProductName() %>
<br>产品单价:<%=p.getProductPrice() %>
<br>包装单位:<%=p.getProductUnit() %>
<br>购买数量:<%=p.getProductQty() %>
<br><b class="text-primary">小计金额:<%=p.getProductPrice() * p.getProductQty()%></b>
</div>
<% } %>
<hr>
<h3 class="text-danger">总计金额:<%=total%></h3>
</div>
</body>
</html>
C02_D05_Listeners


index.html
讯享网<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<title>Servlet相关的监听器</title>
</head>
<body class="bg-danger">
<div class="container">
<h1 class="text-center text-primary">Servlet相关的监听器</h1>
<hr>
<h2>(1). 会话(HttpSession)相关监听器</h2>
<br>
<a href="second.jsp" class="text-danger">* 跳转到页面2</a>
<br><br>
<a href="s1">* 开始会话</a>
<br><br>
<a href="s2">* 结束会话</a>
<br><br>
<a href="s3">* 操作会话中的属性</a>
<hr>
<h2>(2). 上下文(ServletContext)相关监听器</h2>
<br>
<a href="s4">* 操作上下文中的属性</a>
<hr>
<h2>(3). 请求(ServletRequest)相关监听器</h2>
<br>
<a href="s5">* 请求Servlet5</a>
<br><br>
<a href="s6">* 操作请求对象中的属性</a>
<hr>
</div>
</body>
</html>
second.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<title>页面2</title>
</head>
<body>
<div class="container bg-success">
<h1>页面2</h1>
<hr>
<br>
<%=session.getAttribute("name") %>
<br>
<br>
<br>
</div>
</body>
</html>

web.xml
讯享网<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <listener> <description>监听会话的创建和摧毁</description> <listener-class>com.qdu.listener.MySessionListener</listener-class> </listener> <listener> <description>监听会话对象中属性的变化</description> <listener-class>com.qdu.listener.MySessionAttributeListener</listener-class> </listener> <listener> <description>监听上下文对象的创建和摧毁</description> <listener-class>com.qdu.listener.MyContextListener</listener-class> </listener> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>

Servlet1
package com.qdu.servlet;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/s1")
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=req.getSession();
session.setAttribute("name", "Anna");
resp.sendRedirect("index.html");
}
}
MySessionListener
讯享网package com.qdu.listener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; / * 会话监听器(HttpSessionListener) * <br>监听会话对象的创建和摧毁事件 * * @author Anna */ //创建监听器(listener),绝大部分监听器都是接口 //1. 如果想创建对应的监听器类,实现对应的监听器接口即可 //2. 在web.xml中或使用@WebListener注册监听器 //@WebListener public class MySessionListener implements HttpSessionListener{ //该方法响应会话对象被创建而调用,并且自动传入一个参数,参数是一个事件对象 //包含事件发生的信息,如创建的会话 @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("有新会话被创建,会话编号:"+se.getSession().getId()); } //该方法响应会话对象被摧毁而调用,并且自动传入一个参数,参数是一个事件对象 //包含事件发生的信息,如创建的会话 @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("有会话被摧毁,会话编号:"+se.getSession().getId()); } }
MySessionAttributeListener
package com.qdu.listener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; / * 创建会话属性监听器(HttpSessionAttributeListener) * <br>监听会话对象中属性的添加、修改和删除事件 * * @author Anna */ public class MySessionAttributeListener implements HttpSessionAttributeListener{ //当监听到会话中添加了新属性后,attributeAdded()被调用 //并自动传入一个事件对象,包含事件信息 @Override public void attributeAdded(HttpSessionBindingEvent event) { //通过事件对象可以获取添加的属性的信息,或者获取会话对象进行一些操作 //getName()获取添加的属性的名称,getValue()获取添加的属性的值 System.out.println("会话中添加了新属性,属性:"+event.getName()+"-"+event.getValue()); } //当监听到会话中删除了属性后,attributeRemoved()被调用 //并自动传入一个事件对象,包含事件信息 @Override public void attributeRemoved(HttpSessionBindingEvent event) { System.out.println("会话中删除了属性,属性:"+event.getName()+"-"+event.getValue()); } //当监听到会话中修改了一个属性后,attributeReplaced()被调用 //并自动传入一个事件对象,包含事件信息 @Override public void attributeReplaced(HttpSessionBindingEvent event) { System.out.println("会话中修改了属性,属性:"+event.getName()+"-"+event.getValue()); } }





Servlet4
讯享网
package com.qdu.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/s4")
public class Servlet4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//在Servlet中获取程序的上下文对象
//在Servlet中可调用继承的getServletContext()方法获取上下文对象
ServletContext ctx=getServletContext();
//放入上下文对象的属性是整个程序中可用
ctx.setAttribute("count", 1000); //第一次设置一个属性是添加属性
ctx.setAttribute("count", 2000); //第二次设置已有的属性是修改属性
ctx.removeAttribute("count"); //removeAttribute()用于删除一个属性ctx.setAttribute("count", 1000);
resp.sendRedirect("index.html");
}
}

MyContextListener
package com.qdu.listener; //ServletContext Servlet上下文 import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; //一个程序有且仅有一个上下文对象,用于在整个程序期间使用,可用于在程序中共享数据 //你觉得程序的上下文对象什么时候被创建,什么时候被摧毁? / * 创建上下文监听器(ServletContextListener) * <br>监听器上下文对象的初始化和摧毁事件 * * @author Anna */ //程序上下文对象在程序启动的时候就会被创建和初始化 //一般是程序停止或关闭服务器才会导致上下文对象被摧毁 //@WebListener public class MyContextListener implements ServletContextListener{ //当监听器监听到上下文对象被初始化,初始化也就是意味着对象被创建了 //并且自动传入一个事件对象,包含事件信息,可通过该对象获取上下文对象进行操作 @Override public void contextInitialized(ServletContextEvent sce) { //一般如果程序启动就需要加载一些数据到上下文对象中,方便程序后面使用 //一般需要在该方法中写代码 System.out.println("上下文对象被创建!"); } //当监听器到上下文对象被摧毁,该方法被调用 //并且自动传入一个事件对象,包含事件信息,可通过该对象获取上下文对象进行操作 @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("上下文对象被摧毁!"); } }
MyContextAttributeListener
讯享网package com.qdu.listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import javax.servlet.annotation.WebListener; / * 创建上下文属性监听器(ServletContextAttributeListener) * <br>监听上下文对象中属性的添加、修改和删除事件 * * @author Anna */ @WebListener //和在web.xml中使用listener标记注册监听器等效,使用其中一个方式即可 public class MyContextAttributeListener implements ServletContextAttributeListener{ @Override public void attributeAdded(ServletContextAttributeEvent event) { System.out.println("上下文对象中添加了新属性,属性:"+event.getName()+"-"+event.getValue()); } @Override public void attributeRemoved(ServletContextAttributeEvent event) { System.out.println("上下文对象中删除了属性,属性:"+event.getName()+"-"+event.getValue()); } @Override public void attributeReplaced(ServletContextAttributeEvent event) { System.out.println("上下文对象中修改了属性,属性:"+event.getName()+"-"+event.getValue()); } }
Servlet5
package com.qdu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/s5") public class Servlet5 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out=resp.getWriter(); out.println("<h1>Hi, This is Servlet5!</h1>"); } }

MyRequestListener
讯享网package com.qdu.listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServletRequest; / * 创建请求监听器(ServletRequestListener) * <br>监听器请求对象的初始化和摧毁事件 * * @author Anna */ //@WebListener public class MyRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { HttpServletRequest req = (HttpServletRequest) sre.getServletRequest(); System.out.println("摧毁了请求对象,请求路径为:" + req.getRequestURI()); } @Override public void requestInitialized(ServletRequestEvent sre) { HttpServletRequest req = (HttpServletRequest) sre.getServletRequest(); System.out.println("创建了新的请求对象,请求路径为:" + req.getRequestURI()); } }
MyRequestAttributeListener
package com.qdu.listener; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; / * 创建请求属性监听器(ServletRequestAttributeListener) * <br>监听请求对象中属性的添加、修改和删除事件 * * @author Anna */ public class MyRequestAttributeListener implements ServletRequestAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent event) { System.out.println("请求对象中添加了新属性:" + event.getName() + "-" + event.getValue()); } @Override public void attributeRemoved(ServletRequestAttributeEvent event) { System.out.println("请求对象中删除了属性:" + event.getName() + "-" + event.getValue()); } @Override public void attributeReplaced(ServletRequestAttributeEvent event) { System.out.println("请求对象中修改了属性:" + event.getName() + "-" + event.getValue()); } }
Servlet6
讯享网package com.qdu.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/s6")
public class Servlet6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("name", "小强");
req.setAttribute("name", "小红");
req.removeAttribute("name");
resp.sendRedirect("index.html");
}
}


输入5 和 2

被除数是0时

输入字母时

index.html
<!DOCTYPE html>
<html>
<head>
<title>了解状态码</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<br>
<h1 class="text-center text-danger">了解状态码</h1>
<p>* 地址栏Url故意打错或除数输入0或字母查看状态码,该程序要求输入的是整数</p>
<p>* 该程序主要是认识和了解状态码,所以并没有让你们去写任何代码</p>
<hr>
<br>
<form action="cs" class="form-inline">
<table>
<tr>
<td colspan="2">
<h3 class="text-center">计算器</h3>
</td>
</tr>
<tr>
<td>输入被除数:</td>
<td><input type="text" name="num1" class="form-control"></td>
</tr>
<tr>
<td>输入除数:</td>
<td><input type="text" name="num2" class="form-control"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" class="btn btn-sm btn-danger" value="计算">
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
CalculateServlet
讯享网package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/cs")
public class CalculateServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int a=Integer.parseInt(request.getParameter("num1"));
int b=Integer.parseInt(request.getParameter("num2"));
int result=a/b;
response.setContentType("text/html;charset=utf-8");
try (PrintWriter out = response.getWriter()) {
out.println("<br><h1>计算结果:" + result + "</h1>");
}
}
}
C02_D08_HandleError1

index.html
<!DOCTYPE html>
<html>
<head>
<title>处理错误</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
<h1 class="text-center text-danger">处理错误-自定义错误页面</h1>
<hr>
<br>
<ul>
<li><a href="download.html">四六级真题下载园地</a></li>
<li><a href="cet4Answer.jsp">2017年12月四级答案</a></li>
<li><a href="takeCet4Servlet">四级模拟测试</a></li>
<li><a href="secret.html">秘诀-如何取得四级600分</a></li>
</ul>
<br>
<br>
<a href="images/longmao1.gif" title="查看原图">
<img src="images/longmao1.gif" alt="行走的龙猫" width="250" height="182">
</a>
<a href="images/longmao.gif" title="查看原图">
<img src="images/longmao2.gif" alt="行走的龙猫" width="182" height="182">
</a>
</div>
</body>
</html>


目录里并没有这些资源,访问


web.xml
讯享网<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <session-config> <session-timeout> 30 </session-timeout> </session-config> <!--error-page用于配置错误页面--> <error-page> <!--error-code指定针对的错误代码--> <error-code>404</error-code> <!--location:位置,用于指定错误页面的位置,也就是路径--> <location>/error_page.jsp</location> </error-page> </web-app>
error_page.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>这个.. 页面没有找到!!!</title>
<style type="text/css">
body{ margin:0; padding:0; font-family: 微软雅黑; }
div#mother{ margin:0 auto; width:943px; height:572px; position:relative; }
div#errorBox{ background: url(${pageContext.request.contextPath}/images/longmao3.gif) no-repeat center left; width:943px; height:572px; margin:auto; }
div#errorText{ color:#39351e; padding:185px 0 0 456px }
div#errorText p{ width:303px; font-size:14px; line-height:26px; }
div.link{ height:50px; width:145px; float:left;background-color:red;color: black; }
div#home{ margin:0 0 0 444px;}
div#contact{ margin:0 0 0 25px;}
h1{ font-size:40px; margin-bottom:35px; }
</style>
</head>
<body>
<div id="mother">
<div id="errorBox">
<div id="errorText">
<h1>Sorry..页面没有找到!</h1>
<p>似乎你所寻找的网页已移动或丢失了。</p>
<p>请不要担心,这没事。</p>
<p>如果该资源对你很重要,请与<a href="mailto: anna@163.com">管理员</a>联系。</p>
<p>火星不太安全,我可以免费送你回地球!</p>
</div>
</div>
</div>
</body>
</html>
C02_D09_HandleError2

index.html
讯享网<!DOCTYPE html>
<html>
<head>
<title>处理错误和异常</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="container">
<br>
<h1 class="text-center text-danger">处理错误和异常</h1>
<p>* 地址栏Url故意输入0或字母查看状态码,该程序要求输入的是整数</p>
<hr>
<br>
<form action="cs" class="form-inline">
<table>
<tr>
<td colspan="2">
<h3 class="text-center">计算器</h3>
</td>
</tr>
<tr>
<td>输入被除数:</td>
<td><input type="text" name="num1" value="100" class="form-control"></td>
</tr>
<tr>
<td>输入除数:</td>
<td><input type="text" name="num2" value="0" class="form-control"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" class="btn btn-sm btn-danger" value="计算">
</td>
</tr>
</table>
</form>
</div>
</body>
</html>

style.css
h1{ text-align: center; color: brown; } table td{ padding: 5px; }
CalculateServlet
讯享网package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/cs")
public class CalculateServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int num1 = Integer.parseInt(request.getParameter("num1"));
int num2 = Integer.parseInt(request.getParameter("num2"));
int result = 0;
result = num1 / num2;
response.setContentType("text/html;charset=utf-8");
try (PrintWriter out = response.getWriter()) {
out.println("<br><h1>计算结果:" + result + "</h1>");
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<!--可以针对错误代码配置错误页面-->
<!--
<error-page>
<error-code>500</error-code>
<location>/error_500.html</location>
</error-page>
-->
<!--也可针对异常类型配置错误页面-->
<!--exception-type标记指定针对的异常类型-->
<!--
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NumberFormatException</exception-type>
<location>/error.jsp</location>
</error-page>
-->
<!--所有的异常类都直接或间接实现了Throwable接口,所以java.lang.Throwable表示所有异常-->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
</web-app>
error.jsp
讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>异常错误页面</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
</head>
<body class="bg-warning">
<div class="container">
<br>
<h1 class="text-center text-danger">异常错误页面</h1>
<hr>
<!--如果发生异常,转到指定的错误页面(错误页面可以是一个页面或一个servlet),
异常信息会传送到该页面,所以可以获取错误异常信息
服务器通过请求对象的setAttribute()方法将异常信息放入到请求对象
所以在错误页面,可通过请求的getAttribute()方法获取异常信息
-->
<%
out.println("<br>状态代码: " + request.getAttribute("javax.servlet.error.status_code"));
out.println("<br>异常消息: " + request.getAttribute("javax.servlet.error.message"));
out.println("<br>异常类型: " + request.getAttribute("javax.servlet.error.exception_type"));
//获取程序的上下文对象吧
ServletContext ctx = getServletContext();
//也可根据需求自己写入信息到日志
ctx.log("异常消息:"+request.getAttribute("javax.servlet.error.message"));
%>
</div>
</body>
</html>
error_500.html
<!DOCTYPE html>
<html>
<head>
<title>状态代码500-错误页面</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1 style="color: red;text-align: center;">500-服务器端出错,<a href="#">发送</a>信息给管理员!</h1>
</body>
</html>
C02_D10_setStatus

讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>百搜一下,你就知道</title>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<h1>百搜-搜天下</h1>
<form>
<input type="text">
<input type="submit" value="百搜一下">
</form>
<%
//特殊的情况下,需要自行决定发送给客户端的状态码
//可调用以下两个方法
//sendError()方法 用于发送4或5开头的错误代码
//setStatus()方法 用于发送非错误状态代码
//响应报头location用于指定一个目标url
response.setHeader("location","https://www.baidu.com");
//response.setStatus(301);
//永久地 permanently 301永久重定向,说明永久定向导新的地址
//临时地 temporarily 302临时重定向,说明临时定向到新的地址
//除了用对应的数字状态码,也可使用HttpServletResponse接口中的各种常量名
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
//www.tianmao.com
//www.tianmaomao.com
//可以只指定发送的错误代码
//response.sendError(410);
//也可同时指定发送的错误代码和一个消息
//response.sendError(410, "该资源已经永久删除了!");
%>
</body>
</html>
C02_D11_sendError
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>百搜一下,你就知道</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>百搜搜-搜天下</h1>
<form>
<input type="text">
<input type="submit" value="百搜一下">
</form>
<%
//可以只指定发送的错误代码
//response.sendError(410);
//也可同时指定发送的错误代码和一个消息
//response.sendError(410, "该资源已经永久删除了!");
%>
</body>
</html>

style.css
讯享网body{font-family:微软雅黑;} h1{text-align: center; color:darkcyan;margin-top: 100px;} form{width: 650px; margin: 50px auto;} input[type="text"]{width: 500px; height: 40px; outline: none; border: solid 1px lightblue; padding: 0 10px; border-radius: 5px;} input[type="submit"]{width: 100px; height: 42px;border-radius: 5px; background-color: chocolate; border: none; color: white; font-size: 18px;} input[type="submit"]:hover{cursor: pointer; background-color: crimson;}

C02_D12_RequestDispatch_ResponseRedirect


index.html
<!DOCTYPE html>
<html>
<head>
<title>请求转发和响应重定向</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
<br>
<h1 class="text-center text-danger">请求转发和响应重定向</h1>
<hr>
<br>
<ul>
<li><a href="firstServlet?flag=1">1. 响应重定向-sendRedirect</a></li>
<li><a href="firstServlet?flag=2">2. 请求转发-forward</a></li>
<li><a href="firstServlet?flag=3">3. 请求转发-include</a></li>
</ul>
</div>
</body>
</html>
second.jsp
讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>页面second</title>
</head>
<body>
<div style="color:red;">
<p></p>
<h1>页面second的内容</h1>
<!--获取一下请求参数flag的值,看看是不是同一个请求对象-->
<p>请求参数flag: <%=request.getParameter("flag")%> </p>
<p>请求中的属性: <%=request.getAttribute("number")%> </p>
<p></p>
</div>
</body>
</html>
1

FirstServlet
package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/firstServlet")
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out=resp.getWriter();
out.println("<br><h1>这是FirstSevlet输出的内容-开始</h1>");
//获取请求参数flag的值并将其转换成整数
int flag=Integer.parseInt(req.getParameter("flag"));
switch(flag){
case 1: //实现重定向
//1)最后显示重定向后资源的内容
//2) 地址栏显示重定向后的资源的url
//3) 整个过程中产生了2个请求,重定向是发起一个新请求,请求重定向后的资源(页面或servlet等)
resp.sendRedirect("second.jsp"); //重定向到second.jsp
break;
case 2: //调用forward()方法转发请求
//1)最后显示转发后的资源的内容
//2) 地址栏显示转发向前的资源的url
//3) 整个过程中产生了1个请求
//request请求 dispatch派遣、派发 forward转发
//请求对象的getRequestDispatcher()用于获取一个可以派发/转发请求的请求派发器对象
//一个RequestDispatcher对象是可以用于派发请求的对象,需要指定转发目标,也就是请求转发给谁
//目标的url可以用相对路径或类似绝对路径(/开头)
//RequestDispatcher rd=req.getRequestDispatcher("/second.jsp");
//调用forward()方法转发请求即可
//该方法接受两个参数,表示要转发的请求对象和响应对象
//这样导致转发请求的组件(servlet或jsp)和目标组件(servlet或jsp)收到的请求对象和响应对象都是同一个
//rd.forward(req, resp);
//也可获取了请求派遣器对象后直接操作,而不用变量接收请求派遣器对象
//如果产生了一些数据,需要共享给下个组件(servlet或jsp),一般选择转发请求
//可以将数据作为属性放入请求对象,然后转发请求
req.setAttribute("number",666666);
req.getRequestDispatcher("/second.jsp").forward(req, resp);
break;
case 3: //调用include()方法转发请求,将转发后的组件(second.jsp)的内容包含到当前组件(FirstServlet)中显示
//A->B forward转发 B
//A->B include转发 A+B
//1)最后显示转发前+后的资源的内容
//2) 地址栏显示转发向前的资源的url
//3) 整个过程中产生了1个请求
req.getRequestDispatcher("/second.jsp").include(req, resp);
break;
}
out.println("<h1>这是FirstSevlet输出的内容-结束</h1>");
}
}




C02_D13_ThreadModel1

index.html
讯享网<!DOCTYPE html>
<html>
<head>
<title>Servlet线程模型</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css"/>
</head>
<body style="background-color: antiquewhite;">
<h1>Servlet线程模型-多线程模型和单线程模型</h1>
<hr>
<br>
<a class="sa" href="servletA">请求ServletA-抽小奖</a>
<a class="sb" href="servletB">请求ServletB-抽大奖</a>
</body>
</html>
style.css
h1{ color: darksalmon; text-align: center; } a{ display: block; width: 200px; height: 40px; line-height: 40px; margin: 30px auto; background-color: darkcyan; color: white; text-align: center; text-decoration: none; } a.sb{ background-color: red; } a:hover{ text-decoration: underline; background-color: brown; }
ServletA
讯享网package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//默认一个Servlet使用多线程模型处理请求, 单实例,多线程
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
//一旦一个Servlet被实例化之后,接着会被初始化,所以初始化了,说明已经实例化
//init()
//service()->doGet()/doPost()
//destroy()
//所以可以重写init()方法看看实例化几次
@Override
public void init() throws ServletException {
System.out.println("ServletA被实例化!!!");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Random rand = new Random();
int money = rand.nextInt(10001) + 10000;
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println("<br><h1 style='text-align: center;'>ServletA</h1>");
out.println("<hr><br><br>");
if (money % 3 == 0) {
out.println("<h1 style='text-align: center; color: red;'>恭喜您中得" + money + "元,随便花!</h1>");
} else {
out.println("<h1 style='text-align: center; color: black;'>很遗憾,您未中奖,还是好好学习吧!</h1>");
}
}
}
}


ServletB
package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//单线程模型: 多实例,多线程,需要实现SingleThreadModel接口,就可以应用单线程模型
@WebServlet("/servletB")
public class ServletB extends HttpServlet implements SingleThreadModel{
@Override
public void init() throws ServletException {
System.out.println("ServletB被实例化.............");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Random rand = new Random();
int money = rand.nextInt(1000001) + 1;
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println("<br><h1 style='text-align: center;'>ServletB</h1>");
out.println("<hr><br><br>");
if (money % 7 == 0) {
out.println("<h1 style='text-align: center; color: red;'>恭喜您中得" + money + "元,随便花!</h1>");
} else {
out.println("<h1 style='text-align: center; color: black;'>很遗憾,您未中奖,革命尚未成功,同志仍需努力啊!</h1>");
}
}
}
}


C02_D14_ThreadModel2_Synchronization


index.html
讯享网
<html>
<head>
<title>Servlet线程模型-同步化</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<br>
<h1>Servlet线程模型-同步化(Synchronization)</h1>
<hr>
<br>
<!--withdraw 取款-->
<!--deposit 存款-->
<form action="ws">
<label for="un">取款人:</label>
<input id="un" type="text" name="username" placeholder="在此输入取款人姓名">
<br><br>
<label for="acc">取自账户:</label>
<input id="acc" type="text" disabled value="621226 3803001183734">
<br><br>
<label for="accName">账户户名:</label>
<input id="accName" type="text" disabled value="李凡凡">
<br><br>
<input type="submit" value="取款100块">
</form>
</body>
</html>
style.css
h1{ color: darksalmon; text-align: center; } label{ width: 90px; display: inline-block; } input[type="text"]{ padding: 5px 10px; border:solid 1px lightblue; outline: none; border-radius: 5px; } input[type="submit"]{ width: 290px; height: 40px; line-height: 40px; background-color: darkcyan; color: white; text-align: center; border:none; border-radius: 5px; } input[type="submit"]:hover{ background-color: brown; cursor: pointer; }
Account
讯享网package com.qdu.entity; import java.util.logging.Level; import java.util.logging.Logger; / * 银行账户类 * * @author NIIT */ public class Account { String name; //账户持有人姓名 int balance; //余额 public Account(String name, int balance) { this.name = name; this.balance = balance; } / * 传入取款人姓名,从一个账户取款100块 * * @param who 取款人的姓名 */ //withdraw 取款 //deposit 存款 //synchronized用于同步化一个方法,同步化的方法同一时刻只能由一个线程访问 public synchronized void withdraw100(String who) { try { System.out.println(who + "取款前余额:" + balance); balance -= 100; //账户余额减少100 Thread.sleep(1000); //休眠1s System.out.println(who + "取款后余额:" + balance); } catch (InterruptedException ex) { ex.printStackTrace(); } } }
WithdrawServlet
package com.qdu.servlet;
import com.qdu.entity.Account;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ws")
public class WithdrawServlet extends HttpServlet {
Account account = new Account("李凡凡", 2000);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("username");
//取款100块
account.withdraw100(name);
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println("<h1>" + name + "同志取款100成功!</h1>");
}
}
}
C02_D15_UseFilter1

index.html
讯享网<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>登录页面</title>
<link rel="stylesheet" href="css/login.css">
</head>
<body>
<br>
<br>
<div id="container">
<br>
<form method="post" action="ls.do">
<table>
<caption>用户登录</caption>
<tr>
<td>账户:</td>
<td><input name="username" type="text" value="李凡凡"></td>
</tr>
<tr>
<td>密码:</td>
<td><input name="password" type="password" value="1234"></td>
</tr>
<tr class="foot">
<td colspan="2">
<input type="submit" value="登录">
<a href="register.html">注册</a>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>


LoginServlet
package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ls.do")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//可以修改请求的编码,但是一定要在获取请求参数前修改编码
//这样可以解决中文参数乱码问题,但是这里的方式只适用于post请求
//req.setCharacterEncoding("utf-8"); //该程序使用过滤器实现修改请求编码,所以这里不用了
String uname = req.getParameter("username");
String pwd = req.getParameter("password");
resp.setContentType("text/html;charset=utf-8");
try (PrintWriter out = resp.getWriter()) {
out.println("<h1>登录信息</h1>");
out.println("<hr>");
out.println("<br>账号:" + uname);
out.println("<br><br>密码:" + pwd);
}
}
}
register.html
讯享网<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>注册页面</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/register.css">
</head>
<body>
<div class="container">
<h1 class="text-primary text-center">学生注册</h1>
<hr>
<form method="post" action="rs.do" class="form-inline">
<table>
<tr>
<td><label for="srollno">学号:</label></td>
<td><input name="srollno" class="form-control" type="text" id="srollno" value="2017209999"></td>
</tr>
<tr>
<td><label for="spwd">密码:</label></td>
<td><input name="spwd" class="form-control" type="password" id="spwd" value="666666"></td>
</tr>
<tr>
<td><label for="sname">姓名:</label></td>
<td><input name="sname" class="form-control" type="text" id="sname" value="李凡凡"></td>
</tr>
<tr>
<td><label for="sgender">性别:</label></td>
<td>
<select name="sgender" id="sgender" class="form-control">
<option value="男">男</option>
<option value="女">女</option>
</select>
</td>
</tr>
<tr>
<td><label for="sbatch">班级:</label></td>
<td>
<select name="sbatch" id="sbatch" class="form-control">
<option value="17软件(Java)03">17软件(Java)03</option>
<option value="17软件(Java)04">17软件(Java)04</option>
<option value="17软件(Java)06">17软件(Java)06</option>
</select>
</td>
</tr>
<tr class="foot">
<td colspan="2" class="text-center">
<input type="submit" value="注册" class="btn btn-sm btn-primary">
</td>
</tr>
</table>
</form>
</div>
</body>
</html>


package com.qdu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/rs.do")
public class RegisterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String srollno = req.getParameter("srollno");
String spwd = req.getParameter("spwd");
String sname = req.getParameter("sname");
String sgender = req.getParameter("sgender");
String sbatch = req.getParameter("sbatch");
resp.setContentType("text/html;charset=utf-8");
try (PrintWriter out = resp.getWriter()) {
out.println("<h1>注册信息</h1>");
out.println("<hr>");
out.println("<br>学号:"+srollno);
out.println("<br><br>密码:"+spwd);
out.println("<br><br>姓名:"+sname);
out.println("<br><br>性别:"+sgender);
out.println("<br><br>班级:"+sbatch);
}
}
}
EncodingFilter
讯享网package com.qdu.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; / * 创建一个过滤器,用于拦截包含中文参数的post请求,修改请求编码,然后放行请求去访问实际资源 * <br>创建过滤器的步骤 * <br>1. 实现Filter接口,创建过滤器类 * <br>2. 在web.xml中或使用@WebFilter注解注册过滤器才能使用过滤器 * * @author NIIT */ //过滤器在程序启动的时候就会实例化,可以看下init()方法中的代码在程序启动的时候就会输出 public class EncodingFilter implements Filter { //init()方法在过滤器实例化后被调用,该方法被调用说明过滤器被实例化了 //如果在过滤器拦截请求之前需要做一些初始工作,在此方法中编写代码 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init被调用了!!!......;."); } //过滤器应该执行的逻辑代码在此方法编写,也就是过滤器需要实现的功能 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //该方法接收三个参数 //1. 表示拦截的请求对象 //2. 表示拦截的响应对象 //3. 一个FilterChain对象,表示过滤器链,可用于操作过滤器链上的过滤器 //可以在控制台观察下面这行代码的输出判断过滤器的doFitler()方法什么时候被调用 System.out.println("doFitler被调用..............."); request.setCharacterEncoding("utf-8"); //修改请求编码 //FilterChain接口的doFilter()方法的调用导致过滤器链上的下一个过滤器被调用 //如果没有下一个过滤器,则导致过滤器链上终端的实际资被调用,也就是请求到达实际资源 chain.doFilter(request, response); //放行请求去访问资源 } //destroy()方法在一个过滤器实例被摧毁前调用,用于释放资源 @Override public void destroy() { System.out.println("destroy被调用!!!........"); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<!--filter标记用于指定一个过滤器的名称、描述和类名-->
<filter>
<description>拦截包含中文参数的post请求,修正请求编码</description>
<filter-name>encodingFilter</filter-name>
<filter-class>com.qdu.filter.EncodingFilter</filter-class>
</filter>
<!--如果想拦截某种类型的请求,可以考虑请求路径具有相同的后缀(如*.do)或前缀(如/post/*)-->
<!--filter-mapping标记指定一个过滤器的映射,也就是过滤器过滤什么样的请求,也就是拦截什么样的请求-->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<!--<url-pattern>/ls</url-pattern>-->
<!--<url-pattern>/rs</url-pattern>-->
<url-pattern>*.do</url-pattern>
<!--<url-pattern>/post/*</url-pattern>-->
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
</web-app>
login.css
讯享网@charset "utf-8"; #container{ width: 280px; margin: 50px auto 0 auto; background-color:#CC0; } table{ width:100%; border-spacing: 10px; } table caption{ background-color:#C60; padding: 10px 0 10px 0; font-size: 30px; font-weight: bold; color: white; } input[type="text"],input[type="password"],select{ padding:5px 10px; border: none; outline:none; border-radius: 5px; } input[type="submit"],a{ width: 70px; height: 30px; line-height: 30px; background-color: darkcyan; color: white; text-align: center; border:none; border-radius: 5px; } a{ display: inline-block; text-decoration: none; } input[type="submit"]:hover{ background-color: brown; cursor: pointer; } a{ background-color: darkorange; } a:hover{ text-decoration: underline; background-color: brown; } table tr.foot{ text-align: center; }
register.css
@charset "utf-8"; #container{ width: 320px; margin: 50px auto 0 auto; background-color:#CC0; } table{ border-spacing: 20px; width:270px; margin: 30px auto; } table td{ padding: 6px; } select{ width: 196px!important; } .gender{ margin-left: 5px; margin-right: 10px; } .gender:hover{ cursor: pointer; text-decoration: underline; }
C02_D16_UseFilter2


login.html
讯享网<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>登录页面</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<br>
<br>
<div id="container">
<br>
<form method="post" action="ls">
<table>
<caption>用户登录</caption>
<tr>
<td>账户:</td>
<td><input name="username" type="text" value="anna"></td>
</tr>
<tr>
<td>密码:</td>
<td><input name="password" type="password" value="123"></td>
</tr>
<tr class="foot">
<td colspan="2">
<input type="submit" value="登录">
<a href="#">注册</a>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
这里的登录和注册虽然都是按钮,但一个是提交按钮,一个是超链接。
LoginServlet
package com.qdu.servlet;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/ls")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uname=request.getParameter("username");
String pwd=request.getParameter("password");
if(uname.equals("anna")&&pwd.equals("123")){
//通过请求对象可以获取关联的会话
HttpSession session=request.getSession();
//添加一项信息到会话对象中,表示登录状态,如果会话中有isLogin这个属性,则说明用户登录了
session.setAttribute("isLogin","Y");
response.sendRedirect("loginSuccess.jsp");
}else{
response.sendRedirect("loginFail.html");
}
}
}

loginSuccess.jsp
讯享网<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>登录成功</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="background-color: darkkhaki;">
<h1>欢迎登录,您可以去下载资源了</h1>
<hr>
<ul style="line-height: 30px;">
<li><a href="resources/download.jsp">下载园地</a></li>
<li><a href="resources/forum.jsp">学习论坛</a></li>
<li><a href="resources/video.jsp">学习视频</a></li>
<li><a href="contact.html">联系我们</a></li>
</ul>
<a href="los">退出登录</a>
</body>
</html>
LogoutServlet
package com.qdu.servlet;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/los")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
response.sendRedirect("login.html");
}
}

讯享网<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1 style="color: red;">登录失败,请<a href="javascript:history.back();">返回</a>重新登录!</h1>
</body>
</html>
LoginFilter
package com.qdu.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/
* 创建一个过滤器,拦**问resources目录下所有资源的请求
* <br>拦截请求后判断用户是否已经登录,如果登录,放行请求访问实际资源
* <br>否则不放行,将用户重定向到warning.html
*
* @author NIIT
*/
public class LoginFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init..................");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("doFilter...............");
//getSession()方法是HttpServletRequest接口的方法,ServletRequest接口没有该方法
//但是实际发送的请求是Http请求,所以实际发送的请求是HttpServletRequest类型
//需要手动转换类型到HttpServletRequest类型
HttpServletRequest req=(HttpServletRequest)request;
//sendRedirect()方法是HttpServletResponse接口的,所以响应对象也要转换类型
HttpServletResponse resp=(HttpServletResponse)response;
//如果还没有会话对象,说明没登录,我们也不希望在过滤器中创建对象
//所以调用getSession(false)表示有会话返回会话对象,没有返回null
HttpSession session=req.getSession(false);
//如果会话不为null,并且会话中有isLogin这个属性(该属性不为null说明有该属性)d
if(null!=session&&null!=session.getAttribute("isLogin")){
chain.doFilter(request, response); //放行请求去访问资源
}else{
//else说明没有登录,则不调用FilterChain的doFilter()方法
//但是这里不能使用相对路径,所以需要获取程序的上下文路径,再追加上warning.html,使用该页面的完整路径
//该程序的上下文路径是http://localhost:8084/C02_D16_UseFilter2
String ctxPath=req.getContextPath()+"/"; //获取程序的上下文路径
//ctxPath+"warning.html形成的路径是http://localhost:8084/C02_D16_UseFilter2/warning.html
resp.sendRedirect(ctxPath+"warning.html"); //这里使用warning.html的完整路径
}
}
@Override
public void destroy() {
}
}
style.css
讯享网@charset "utf-8"; #container{ width: 280px; margin: 50px auto 0 auto; background-color:#CC0; } table{ width:100%; border-spacing: 10px; } table caption{ background-color:#C60; padding: 10px 0 10px 0; font-size: 30px; font-weight: bold; color: white; } input[type="text"],input[type="password"],select{ padding:5px 10px; border: none; outline:none; border-radius: 5px; } input[type="submit"],a{ width: 70px; height: 30px; line-height: 30px; background-color: darkcyan; color: white; text-align: center; border:none; border-radius: 5px; } a{ display: inline-block; text-decoration: none; } input[type="submit"]:hover{ background-color: brown; cursor: pointer; } a{ background-color: darkorange; } a:hover{ text-decoration: underline; background-color: brown; } table tr.foot{ text-align: center; }
web.html
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<filter>
<description>拦截所有对resources目录下资源的访问请求,根据登录判断决定是否可以访问资源</description>
<filter-name>loginFilter</filter-name>
<filter-class>com.qdu.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/resources/*</url-pattern>
<!--
/rs 拦截对rs这个servlet的访问请求
/second.jsp 拦截对单个页面second.jsp的请求
*.do 拦截所有以.do结尾的请求,比较常见的后缀是*.do或*.action等
*.post 拦截所有以.post结尾的请求
/post/* 拦截所有以post前缀的请求
/resources/* 拦截所有以resources为前缀的请求
/resources/*.jsp 不合法-->
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
</web-app>
C02_D17_UseFilter3

LoginFilter
讯享网package com.tianmao.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/
* 创建一个过滤器,拦**问resources目录下所有资源的请求
* <br>拦截请求后判断用户是否已经登录,如果登录,放行请求访问实际资源
* <br>否则不放行,将用户重定向到warning.html
*
* @author NIIT
*/
public class LoginFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init..................");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("doFilter...............");
//getSession()方法是HttpServletRequest接口的方法,ServletRequest接口没有该方法
//但是实际发送的请求是Http请求,所以实际发送的请求是HttpServletRequest类型
//需要手动转换类型到HttpServletRequest类型
HttpServletRequest req=(HttpServletRequest)request;
//sendRedirect()方法是HttpServletResponse接口的,所以响应对象也要转换类型
HttpServletResponse resp=(HttpServletResponse)response;
//如果还没有会话对象,说明没登录,我们也不希望在过滤器中创建对象
//所以调用getSession(false)表示有会话返回会话对象,没有返回null
HttpSession session=req.getSession(false);
//如果会话不为null,并且会话中有isLogin这个属性(该属性不为null说明有该属性)d
if(null!=session&&null!=session.getAttribute("isLogin")){
chain.doFilter(request, response); //放行请求去访问资源
}else{
//else说明没有登录,则不调用FilterChain的doFilter()方法
//但是这里不能使用相对路径,所以需要获取程序的上下文路径,再追加上warning.html,使用该页面的完整路径
//该程序的上下文路径是http://localhost:8084/C02_D16_UseFilter2
String ctxPath=req.getContextPath()+"/"; //获取程序的上下文路径
//ctxPath+"warning.html形成的路径是http://localhost:8084/C02_D16_UseFilter2/warning.html
resp.sendRedirect(ctxPath+"warning.html"); //这里使用warning.html的完整路径
}
}
@Override
public void destroy() {
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <filter> <description>拦截包含中文参数的post请求,判断是否登录</description> <filter-name>LoginFilter</filter-name> <filter-class>com.tianmao.filter.LoginFilter</filter-class> </filter> <!--如果想拦截某种类型的请求,可以考虑请求路径具有相同的后缀(如*.do)或前缀(如/post/*)--> <!--filter-mapping标记指定一个过滤器的映射,也就是过滤器过滤什么样的请求,也就是拦截什么样的请求--> <filter-mapping> <filter-name>LoginFilter</filter-name> <!--<url-pattern>/ls</url-pattern>--> <!--<url-pattern>/rs</url-pattern>--> <url-pattern>/cs</url-pattern> <!--<url-pattern>/post/*</url-pattern>--> </filter-mapping> <filter-mapping> <filter-name>LoginFilter</filter-name> <!--<url-pattern>/ls</url-pattern>--> <!--<url-pattern>/rs</url-pattern>--> <url-pattern>/los</url-pattern> <!--<url-pattern>/post/*</url-pattern>--> </filter-mapping> <filter-mapping> <filter-name>LoginFilter</filter-name> <!--<url-pattern>/ls</url-pattern>--> <!--<url-pattern>/rs</url-pattern>--> <url-pattern>/ps</url-pattern> <!--<url-pattern>/post/*</url-pattern>--> </filter-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/34733.html