第四章:Request和Response
第一节:Request与Response原理和继承体系
1.1 Request对象和Response对象原理
- request和response对象是由服务器创建的,我们只是来使用它们而已
- request对象是来获取请求消息的,response对象是来设置响应消息的
1.2 request对象继承体系结构
-
ServletRequest
:是一个接口 -
HttpServletRequset
:是一个接口,继承自ServletRequest
-
org.apache.catalina.connector.RequestFacade
:是一个类,实现HttpServletRequset
接口,由Tomcat编写
第二节:Request获取请求数据
2.1 获取请求消息数据
1、获取请求行数据
GET/day14/demo01?name=zhangsan HTTP/1.1
方法:
- 获取请求方式:GET
String getMethod()
- 获取虚拟目录:/day14
String getContextPath()
- 获取Servlet路径:/demo01
String getServletPath()
- 获取GET方式的请求参数:name=zhangsan
String getQueryString()
- 获取请求的URI:/day14/demo01
String getRequestURI()
:/day14/demo01String getRequsetURL()
:http://localhost/day14/demo01 - 获取协议及版本号:HTTP/1.1
String getProtocol()
- 获取客户机的IP地址:
String getRemoteAddr()
2、获取请求头数据
方法:
- 通过请求头的名称获取头的值
String getHeader(String name)
- 获取所有的请求头名称
Enumeration<String> getHeaderNames()
Enumeration<String>
:枚举接口,可以理解为迭代器,把它当作迭代器使用
3、获取请求体数据
**请求体:**只有post请求方式,才有请求体,在请求体中封装了post请求的请求参数
步骤:
- 获取流对象
BufferedReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据 - 再从流对象中拿数据
2.2 其他功能
1、获取请求参数通用方式
不论post还是get都能使用下列方法
-
String getParameter(String name)
:根据参数名称获取参数值 -
String[] getParamaterValues(String name)
:根据参数名称获取参数值的数组 -
Enumeration<String> getParameterNames()
:获取所有请求的参数名称 -
Map<String,String[]> getParameterMap()
:获取所有参数的map集合
2、请求转发
**请求转发:**一种在服务器内部的资源跳转方式
- 步骤:
- 通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:
forward(ServletRequest request,ServletResponse response)
- 特点:
- 浏览器地址栏路径没有发生变化
- 只能转发到当前的服务器内部资源中
- 转发是一次请求
3、共享数据
**域对象:**一个有作用范围的对象,可以在范围内共享数据
**request域:**代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
-
viod setAttribute(String name,Object obj)
:存储数据 -
Object getAttribute(String name)
:通过键获取值 -
void removeAttribute(String name)
:通过键移除键值对
4、获取ServletContext
-
ServletContext getServletContext()
:获取ServletContext
2.3 中文乱码问题
**get方式:**tomcat 8 已经将get方式乱码问题解决了
**post方式:**会乱码
**解决:**在获取参数前,设置request的编码
request.setCharacterEncoding("utf-8");
第三节:案例-用户登录
用户登陆案例需求:
- 编写login.html登陆界面
- 使用Druid数据库连接池技术,操作mysql,all中userlogin表
- 使用JDBCTemplate技术封装JDBC
- 登陆成功跳转到SuccessServlet展示:登陆成功!用户名欢迎您
- 登陆失败跳转到FFailServlet展示:登陆失败,用户名或密码错误
开发步骤:
- 创建项目,导入html页面配置文件与jar包
- 创建数据库的环境
- 创建实体类
- 创建UserDao类,提供login()方法
- 创建类UserDao2,提供login方法
- 创建LoginServlet2类
- form表单的action写法:虚拟目录+Servlet的资源路径
- BeanUtils工具类,简化数据封装
3.2 BeanUtils介绍
BeanUtils工具类:简化数据封装
- JavaBean:标准的Java类
- 要求:
- 类必须被public修饰
- 必须提供空参的构造方法
- 成员变量必须使用private修饰
- 提供公共setter和getter方法
- 功能:封装数据
- 概念:
- 成员变量
- 属性:setter和getter方法截取后的产物
例如:getUsername()---->Useername---->username
- 方法
- setProperty()
- getProperty()
- populate(Object,Map):将Map集合的键值对信息,封装到对应的JavaBean对象中
第四节:HTTP响应协议
4.1 概述
**请求消息:**客户端发送给服务器端的数据
- 数据格式:
- 请求行
- 请求头
- 请求空行
- 请求体
**响应消息:**服务器端发送给客户端的数据
- 数据格式:
- 响应行
- 组成:协议/版本 响应状态码 状态码描述
- 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
- 状态码都是三位数字
- 分类:
- 1xx:服务器接收客户端消息但没有接收完成,等待一段时间后,发送1xx状态码
- 2xx:成功。代表:200
- 3xx:重定向。代表:302(重定向) 304(访问缓存)
- 4xx:客户端错误。
代表:404(请求路径没有对应的资源)
405(请求方式没有对应的doxx方法) - 5xx:服务器端错误。代表:500(服务器内部出现异常)
- 响应头
- 格式:头名称:值
- 常见的响应头:
- Content-Type:服务器告诉客户端本次的响应消息体数据格式以及编码格式
- Content-disposition:服务器告诉客户端以什么格式打开响应体数据
值:
- in-line:默认值,在当前页面内打开
- attachment;filename=xxx:以附件形式打开响应体。文件下载
- 响应空行
- 响应体:真实的传输的数据
- 响应的字符串格式:
HTTP/1.1 200 OK
content-type: text/html
date: Thu, 15 Apr 2021 09:48:43 GMT
x-frame-options: SameOrigin
X-Content-Type-Options: nosniff
x-xss-protection: 1; mode=block
accept-ranges: bytes
cache-control: private, must-revalidate
last-modified: Thu, 15 Apr 2021 09:47:07 GMT
content-length: 155
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello Response</title>
</head>
<body>
Hello Response
</body>
</html>
第五节:response之重定向
5.1 response功能
功能:设置响应消息
- 设置响应行
- 格式:HTTP/1.1 200 ok
- 设置状态码:
setStatus(int sc)
- 设置响应头
setHeader(String name,String value)
- 设置响应体
使用步骤:
- 获取输出流
- 字符输出流:
PrintWriter getWriter()
- 字节输出流:
ServletOutputStream getOutputStream()
- 使用数据流,将数据输出到客户端浏览器
5.2 案例
- 完成重定向
- **重定向:**资源跳转的方式
- 代码实现
setHeader(String name,String value)
sendRedirect(String value)
- 重定向(redirect)的特点:
- 地址栏发生变化
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求,不能使用request共享数据
转发(forward)的特点:
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象共享资源
- 路径写法
- 服务器输出字符数据到浏览器
步骤:
- 获取字符输出流
ServletOutputStream sos=resp.getOutputStream();
- 输出数据
sos.write("你好".getBytes("utf-8"));
注意:
乱码问题:
PrintWriter pw=resp.getWriter();
获取的流默认编码是ISO-8859-1的- 设置该流的默认编码
- 告诉浏览器响应体使用的编码
简单的形式(在获取流之前):resp.setContentType("text/html;charset=utf-8");
复杂的形式:resp.setHeader("content-type","text/html;charset=utf-8");
- 服务器输出字节数据到浏览器
- 验证码
- 实质:是一张图片
- 目的:防止恶意表单注册
5.3 路径
相对路径
通过相对路径不可以确定唯一资源
如:./index.html
不以/开头,以.开头的路径
**规则:**找到当前资源和目标资源之间的相对位置关系
**./😗*当前目录
…/:后退一级目录
绝对路径
通过绝对路径可以确定唯一资源
如:http://localhost/day15/responseDemo02
可以省略为:/day15/responseDemo02
以/开头的路径
**规则:**判断定义的路径是给谁用的(判断请求将来从哪发出)
- 给客户端浏览器:需要加虚拟目录(项目的访问路径)
建议虚拟目录动态获取:request.getContextPath()
<a>,<form>,重定向...
- 给服务器:不需要加虚拟目录
转发路径
5.4 ServletContext对象
- **概念:**代表整个web应用,可以和程序的容器(服务器)来通信
- 获取:
- 通过request对象来获取
request.getServletContext();
- 通过httpServlet获取
this.getServletContext();
- 功能:
- 获取MIME类型:
MIME类型:在互联网通信过程中定义的一种文件数据类型
格式:大类型/小类型 text/html image/jpeg
获取:String getMimeType(String file)
- 域对象:共享数据
setAttribute(String name,Object value)
getAttribute(String name)
removeAttribute(String name)
**ServletContext对象范围:**所有用户所有请求的数据
- 获取文件的真实路径(服务器路径)
- 方法:
String getRealPath(String path)
5.5 文件下载案例
文件下载需求:
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件的下载
分析:
- 超链接指向的资源如果能被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
- 任何资源都必须弹出下载提示框
- 任何响应头设置资源的打开方式:
content-disposition:attachment;filename-xxx
步骤:
- 定义页面,编辑超链接href属性,指向Servlet,传递资源的名称filename
- 定义Servlet
- 获取文件的名称
- 使用字节输入流加载文件进内存
- 指定responese的响应头:
content-disposition:attachment;filename-xxx
- 将数据写出到response输出流
问题:
中文文件问题:
解决思路:
- 获取客户端使用的浏览器版本信息
- 根据不同的版本信息,设置filename的编码方式不同
@WebServlet(urlPatterns = "/downLoadServlet")
public class downLoadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求参数,文件名称
String filename=req.getParameter("filename");
//2.使用字节输入流进内存
//2.1找到文件服务器路径
ServletContext sc=this.getServletContext();
String realPath=sc.getRealPath("/img/"+filename);
//2.2用字节流关联
FileInputStream fs=new FileInputStream(realPath);
//3.设置response的响应头
//3.1设置响应头类型:content-type
String mimeType=sc.getMimeType(filename);//获取文件的mime类型
resp.setHeader("content-type",mimeType);
//3.2设置响应头打开方式:content-disposition
//解决中文文件名问题
//1.获取user-agent请求头
String agent=req.getHeader("user-agent");
//2.使用工具类方法编码文件名
filename=DowmLoadUtils.getFilename(agent,filename);
resp.setHeader("content-disposition","attachment;filename="+filename);
//3.将输入流的数据写出到输出流中
ServletOutputStream sos=resp.getOutputStream();
byte[] bytes=new byte[1024];
int len=0;
while ((len=fs.read(bytes))!=-1){
sos.write(bytes,0,len);
}
fs.close();
}
第五章:Cookie和session
第一节:Cookie快速入门
1.1 会话技术
**会话:**一次会话中包含多次请求和响应
**一次会话:**浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
**会话功能:**在一次会话的范围内的多次请求间共享资源
方式:
- 客户端会话技术:Cookie
- 服务器端会话技术:Session
1.2 Cookie快速入门
- **概念:**客户端会话技术,将数据保存到客户端
- 使用步骤:
- 创建Cookie对象,绑定数据
new Cookie(String name,String value)
- 发送Cookie对象
response.addCookie(Cookie cookie)
- 获取Cookie,拿到数据
Cookie[] request.getCookies()
- 实现原理:
- Cookie的细节
- 一次可不可以发送多个Cookie?
可以创建多个Cookie对象,使用response调用多次addCookie()
方法发送Cookie即可 - Cookie在浏览器中保存多长时间?
- 默认情况下,当浏览器关闭后,Cookie数据被销毁
- 设置Cookie的生命周期,使它持久化存储
setMaxAge(int seconds)
- 正数:持久化将Cookie数据写入到硬盘文件中,持久化存储。也是Cookie的存活时间
- 负数:默认值,当浏览器关闭后,Cookie数据被销毁
- 0:删除Cookie信息
- Cookie能不能存中文?
- 在tomcat 8之前,Cookie中不能直接存储中文数据
需要将中文数据转码----一般采用URL编码(%E3)URLEncoder.encode(lastTime,"utf-8");
- 在tomcat 8之后,Cookie支持中文数据.但对特殊字符还是不支持,建议使用URL编码存储,再用URL进行解码取出
URLDecoder.decode(lastTime,"utf-8")
- Cookie共享问题?
- 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中Cookie能不能共享
默认情况下,Cookie不能共享setPath(String path)
:设置Cookie的获取范围。默认情况下,会设置当前的虚拟目录
如果要共享,则可以将path设置为"/" - 不同的tomcat服务器间Cookie共享问题
setDomain(String path)
:如果设置一级域名相同,那么多个服务器之间Cookie可以共享setDomain(".baidu.com")
,那么tieba.baidu.com
和news.baidu.com
中,Cookie可以共享
Cookie的特点和作用
- Cookie存储数据在客户端浏览器
- 浏览器对于单个Cookie的大小(4kb)有限制以及对同一个域名下的总Cookie数量(20个)也有限制
作用:
- Cookie一般用于存储少量的不太敏感的数据
- 在不登陆的情况下,完成服务器对客户端的身份识别
- **案例:**记住上一次访问时间
- 需求:
- 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
- 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
- 分析:
- 可以采用Cookie来完成
- 在服务器中的Servlet判断是否有一个名为lastTime的Cookie
- 有:不是第一次访问
- 欢迎回来,您上次访问时间为:。。。
- 写回Cookie
- 没有:是第一次访问
- 响应数据:您好,欢迎您首次访问
- 写回Cookie:lastTime=。。。
第二节:JSP入门学习
2.1 概念
**Java Server Pages:**Java服务器端页面,可理解为一个特殊的页面,其中即可以直接定义HTML的标签,又可以定义Java代码,用于简化书写
2.2 JSP原理
JSP本质上就是一个Servlet
2.3 JSP脚本
**JSP脚本:**JSP定义Java代码的方式
-
<% Java代码 %>
:定义的Java代码在service方法中。service方法中可以定义什么,该脚本中就可以定义什么 -
<%! Java代码 %>
:定义的Java代码,在JSP转换后的Java类成员位置 -
<%= Java代码 %>
:定义的Java代码,会输出到页面上。输出语句中可以定义什么,他就可以定义什么
2.4 JSP的内置对象
在JSP页面中不需要获取和创建,可以直接使用的对象
JSP一共有9个内置对象,其中的3个为:
request
response
out
:字符输出流对象,可以将数据输出到页面上,和response.getWriter()
类似response.getWriter()
和out.print()
的区别:在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。即:response.getWriter()
数据输出永远在out.print()
之前,建议统一使用out输出,不使用response输出
第三节:Session入门学习
3.1 概念
**Session:**服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
3.2 快速入门
HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name,Object value)
void removeAttribute(String name)
3.3 原理分析
服务器如何确保一次会话范围内,多次获取的Session对象是同一个?
Session的实现是依赖于Cookie的
3.4 Session细节
- 当客户端关闭后,服务器不关闭,两次获取session不是同一个
默认情况下:不是
如果需要相同,则可以创建Cookie,Cookie的键为JSESSIONID
,设置最大存活时间,让Cookie持久化保存
Cookie cookie=new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60*60);
response.addCookie(cookie);
- 客户端不关闭,服务器关闭后,两次获取的session不是同一个
虽然session对象不是同一个,但是要确保数据不丢失
- **session的钝化:**在服务器正常关闭之前,将session对象系列化到硬盘上
- **session的活化:**在服务器启动后,将session文件转化为内存中的session对象即可
- Session什么时候被销毁
- 服务器关闭
- session对象调用
void invalidate()
方法,自己销毁自己 - session默认失效时间为30分钟
选择性的配置修改:在web.xml
文件下找到:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- session的特点:
- session用于存储一次会话的多次请求的数据,存在服务器端
- session可以存储任意类型、任意大小的数据
- session与cookie的区别:
- session存储在服务器端,cookie存储在客户端
- session没有数据大小限制,cookie有大小限制
- session数据安全,cookie数据相对不安全
3.5 案例:验证码
案例需求:
1.访问带有验证码的登录页面login.html
2.用户输入验证码、密码以及用户名
如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
如果验证码输入有误,跳转登录页面,提示:验证码错误
如果全部正确,则跳转到主页success.jsp,显示:用户名,欢迎您
分析:
第四章:JSP,EL和JSTL
4.1 JSP基础语法
- 指令
**作用:**用于配置JSP页面,导入资源页面
格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
分类:
- **page:**配置JSP页面的
contentType
:等同于response.setContentType()
- 设置响应体的mime类型以及字符集
- 设置当前JSP页面的编码(只能是高级的开发工具才能生效,如果使用低级工具,则需要设置
pageEncoding
属性设置当前页面的字符集编码)
-
language
:现在只能写Java -
buffer
:缓冲区的大小,默认为8kb - **
import
:**导包 -
errorPage
:当前页面发生异常后会自动跳转到指定页面 isErrorPage
:标识当前页面是否是错误页面
- **true:**是,可以使用内置对象execption
- **false:**否。默认值,不可以使用内置对象execption
- **include:**页面包含的。导入页面的资源文件
<%@ include file="文件名"%>
- **taglib:**导入资源
<%@taglib prefix="" uri="" %>
**prefix:**前缀,自定义的
- 注释
- html注释:
<!-- -->
:只能注释html代码片段 - JSP注释:
<%-- --%>
:可以注释所有,且不能通过浏览器response查看注释。推荐使用此注释
- 内置对象:在jsp页面中不需要创建,直接使用的对象
变量名 | 真实类型 | 作用 |
pageContext | PageContext | 当前页面共享数据,还可以获取其它八个内置对象 |
request | HttpServletRequest | 一次请求访问的多个资源(转发) |
session | HttpSession | 一次会话的多个请求间 |
application | ServletContext | 所有用户间共享数据 |
response | HttpServletResponse | 响应对象 |
page | Object | 当前页面(Servlet)的对象 |
out | JspWriter | 输出对象,可以把数据输出到页面上 |
config | ServletConfig | Servlet的配置对象 |
execption | Throwable | 异常对象 |
4.2 MVC开发模式
- JSP演变历史
- 早期只有servlet,只能使用response输出标签数据,非常麻烦
- 后来有jap,简化了Servlet的开发,如果过度使用jsp,在jsp中既写大量的Java代码,又写html表,造成难以维护,难以分工协作
- 再后来,Javaweb开发借鉴mvc开发模式,使得程序的设计更加合理性
- MVC
- M:Model,模型。
JavaBean
完成具体的业务操作,如:查询数据库,封装对象 - V:View,视图。
JSP
展示数据 - C:Controller,控制器。
Servlet
- 获取用户的输入
- 调用模型
- 将数据交给视图进行展示
- 优点:
- 耦合性低,方便维护,可以利于分工协作
- 重用性高
- 生命周期成本低
- 部署快
- 可维护性高
- 有利于软件工程管理
- 缺点:
使得项目架构变得复杂,对开发人员要求高很多
4.3 EL表达式
- **概念:**Expression Language 表达式语言
- **作用:**替换和简化jsp页面中Java代码的编写
- 语法:
${表达式}
- 注意:
jsp默认支持EL表达式
如果要忽略EL表达式:
- 设置jsp中page指令中:
isELIgnored="true"
忽略当前jsp页面中所有的el表达式 -
\${表达式}
:忽略当前这个el表达式
- 使用:
- 运算
运算符:
- 算数运算符:
+ - * /(div) %(mod)
- 比较运算符:
> < <= >= == !=
- 逻辑运算符:
&&(and) ||(or) !(not)
- 空运算符:
empty
功能:用于判断字符串、集合、数组对象是否为null并且长度是否为0${empty list}
:判断字符串、集合、数组对象是否为null或者长度为0${not empty str}
:表示判断字符串、集合、数组对象是否不为null,并且长度>0
- 获取值
- el表达式只能从域对象中获取值
- 语法:
${域名称.键名}
:从指定域中获取指定键的值
域名称:
pageScore--->pageContext
requestScope----->request
sessionScope------>session
applicationScope------->application(ServletContext)
举例:在request域中存储了name=张三
获取:${requsetScope.name}
${键名}
:表示依次从最小的域中查找是否有该键对应的值,直到找到为止- 获取对象、List集合、Map集合的值
- 对象:
${域名称.键名.属性名}
本质上会去调用对象的getter方法 - List集合:
${域名称.键名[索引]}
- Map集合:
${域名称.键名.key名称}
或${域名称.键名["key名称"]}
- 隐式对象
EL表达式中有11个隐式对象pageContext
:
- 获取jsp其他八个内置对象:
${pageContext.request.contextPath}
:动态获取虚拟目录
4.4 JSTL常用标签
- 概念:
JavaServer Pages Tag Library
JSP标准标签库
是由Apache组织提供的开源的免费的jsp标签 - **作用:**用于简化和替换jsp页面上的Java代码
- 使用步骤:
- 导入jstl相关jar包
下载页面有4个jar包:
Impl: taglibs-standard-impl-1.2.5.jar JSTL实现类库
Spec: taglibs-standard-spec-1.2.5.jar JSTL标准接口
EL: taglibs-standard-jstlel-1.2.5.jar JSTL1.0标签-EL相关
Compat: taglibs-standard-compat-1.2.5.jar 兼容版本
从README得知:
如果不使用JSTL1.0标签,可以忽略taglibs-standard-jstlel包,
README没有介绍taglibs-standard-compat包,估计应该是兼容以前版本标签库,
所以一般只需要 taglibs-standard-impl 和 taglibs-standard-spec 两个jar包
- 引入标签库:taglib指令:
<%@ taglib %>
- 使用标签
- 常用的JSTL标签:
- **if:**相当于Java代码的if语句
- 属性:
-
test
是必须属性,接收boolean表达式 - 若boolean表达式为true,则显示标签体内容,若boolean表达式为false,则不显示标签体内容
- 一般情况下,test属性值会结合el表达式一起使用
- 注意:
c:if标签没有else情况,想要else情况则可以再定义一个c:if标签
- choose:相当于Java代码的switch语句
- 使用choose标签声明 相当于switch声明
- 使用when标签做判断 相当于case
- 使用otherwise标签做其他情况的声明 相当于default
- foreach:相当于Java代码的for语句
- 完成重复的操作
- 属性:
begin:
开始值
end
:结束值
var
:临时变量
step
:步长
varStatus
:循环状态对象
index
:容器中元素的索引,从0开始
count
:循环次数,从1开始
- 遍历容器
- 属性:
items
:容器对象
var
:容器中元素的临时变量
varStatus
:循环状态对象
index
:容器中元素的索引,从0开始
count
:循环次数,从1开始
- 练习:
需求:在request域中存有User对象的list集合,需要使用jstl+el将list集合数据展示到jsp页面中的表格table中
4.5 综合案例
综合练习:
- 简单功能
- 列表查询
- 登录
- 添加
- 删除
- 修改
- 复杂功能
- 删除选中
- 分页查询
- 复杂条件查询
第五章:Filter和Listener
5.1 Filter概述
生活中的过滤器:纯净器、空气净化器、土匪
**web中的过滤器:**当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
**过滤器的作用:**一般用于完成通用的操作,如登录验证、统一编码处理、敏感字符过滤…
5.2 Filter快速入门
- 步骤:
- 定义一个类,实现接口
Filter
- 复写方法
- 配置拦截路径
web.xml
- 注解配置:
urlPatterns = "/被拦截的文件路径"
5.3 Filter细节
- web.xml配置
<filter>
<filter-name>Filterxml</filter-name>
<filter-class>Filter路径</filter-class>
</filter>
<filter-mapping>
<filter-name>Filterxml</filter-name>
<url-pattern>拦截路径</url-pattern>
</filter-mapping>
- 过滤器执行流程
- 执行过滤器
- 执行放行后的资源
- 回来执行过滤器放行代码下的代码
- 过滤器生命周期方法
-
init()
:在服务器启动后,会创建Filter对象,然后调用init
方法,只执行一次。用于加载资源 -
destroy()
:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法,只执行一次,用于释放资源 -
doFilter()
:每一次请求被拦截资源时,会执行,执行多次
- 过滤器配置详解
- 拦截路径配置:
- 具体资源路径:
/index.jsp
:只有访问index.jsp时,过滤器才会被执行 - 目录拦截:
/user/*
:访问/user下的所有资源时,过滤器都会被执行 - 后缀名拦截:
*.jsp
:访问所有jsp资源时,过滤器都会被执行 - 拦截所有资源:
/*
:访问所有资源时,过滤器都会被执行
- 拦截方式配置:资源被访问的方式
- 注解配置:
- 设置
dispatcherTypes
属性,取值为:
-
DispatcherType.REQUEST
:默认值,浏览器直接请求资源 -
DispatcherType.FORWARD
:转发来访问资源 -
DispatcherType.INCLUDE
:包含访问资源 -
DispatcherType.ERROR
:错误跳转资源 -
DispatcherType.ASYNC
:异步访问资源
- web.xml配置:
- 设置
<dispatcher></dispatcher>
标签即可
-
REQUEST
:默认值,浏览器直接请求资源 -
FORWARD
:转发来访问资源 -
INCLUDE
:包含访问资源 -
ERROR
:错误跳转资源 -
ASYNC
:异步访问资源
- 过滤器链(配置多个过滤器)
- 执行顺序:如果有两个过滤器:过滤器1和过滤器2
- 过滤器1
- 过滤器2
- 资源执行
- 过滤器2
- 过滤器1
- 先后顺序问题:
- 注解配置:按照类名的字符串比较规则比较,值小的先执行
如:AFilter
和BFilter
:AFilter
就先执行了 web.xml
配置:<filter-mapping>
谁定义在上边,谁先执行
5.4 案例
- 登录验证:
需求:
1.访问案例的资源,验证其是否登录
2.如果登陆了则直接放行
如果没有登陆,则跳转到登录页面,提示"您尚未登陆,请先登录"
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.强制转换
HttpServletRequest request=(HttpServletRequest) req;
//1.获取资源请求路径
String uri=request.getRequestURI();
//2.判断是否是登录相关的资源,要注意排除掉css/js/图片/验证码等资源
if (uri.contains("/login.jsp")||uri.contains("/checkServlet")||uri.contains(".css")||uri.contains(".js")||uri.contains("/CheckPic")||uri.contains("/UserServletImpl")){
//包含,证明用户就是想登录,放行
chain.doFilter(req,resp);
}
else {
//不包含,需要验证用户是否登录
//3.从session获取user
Object admin=request.getSession().getAttribute("admin");
if (admin!=null){
//登录了,放行
chain.doFilter(req,resp);
}
else {
//没有登录
request.setAttribute("login_msg","您尚未登陆,请登录");
request.getRequestDispatcher("/UserList/login.jsp").forward(req,resp);
}
}
}
- 敏感词汇过滤:
需求:
1.对案例录入的数据进行敏感词汇过滤
2.敏感词汇参考(敏感词汇.txt)
3.如果是敏感词汇,替换为***
分析:
1.对request对象进行增强。增强获取参数相关方法
2.放行。c
增强对象的功能:
- 设计模式:一些通用的解决固定问题的方式
- 装饰模式:
- 代理模式:
- 概念:
- 真实对象:被代理的对象
- 代理对象
- 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
- 实现方式:
- 静态代理:在有一个类文件描述代理模式
- 动态代理:在内存中形成代理类
实现步骤:
- 代理对象和真实对象实现相同的接口
- 获取代理对象
Proxy.newProxyInstance()
- 使用代理对象调用方法
- 增强方法
方法参数:
invoke(Object proxy, Method method, Object[] args)
- proxy:代理对象
- method:代理对象调用的方法,被封装为的对象
- args:代理对象调用方法时,传递的实际参数
增强方式:
- 增强参数列表
- 增强返回值类型
- 增强方法体执行逻辑
5.5 Listener:监听器
**概念:**web的三大组件之一
- 事件监听机制
- 事件 :一件事情
- 事件源:事件发生的地方
- 监听器:一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。当事件源发生某个事件后,执行监听器代码
servletContextListener
:监听SerletContext对象的创建和替换
- 方法:
void contextDestroyed(ServletContextEvent sce)
:SerletContext对象被销毁之前会调用该方法
void contextInitialized(ServletContextEvent sce)
:SerletContext对象创建后会调用该方法
- 步骤:
- 定义一个类,实现
servletContextListener
接口 - 复写方法
- 配置
- web.xml
<listener>
<listener-class>web.Listener.ContextLoaderListener</listener-class>
</listener>
指定初始化参数:
<context-param>
<param-name>ContextLoaderListener.java</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
第六章:JQuery
第一节:JQuery基础
1.1 概念
JQuery:一个JavaScript框架,简化js开发,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。JQuery设计的宗旨是:write less,do more
,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,简化HTML文档操作、事件处理、动画设计和Ajax交互
**JavaScript框架:**本质上就是一些js文件,封装了js的原生代码而已
1.2 快速入门
- 步骤:
- 下载JQuery
目前JQuery有三个大版本:
1.x:兼容ie678,使用最为广泛,官方只做bug维护
功能不再新增,因此一般项目来说,使用1.x版本就可以了
最终版本:1.12.4(2016年5月20日)
2.x:不兼容ie678,很少有人使用,官方只做bug维护
功能不再新增,如果不考虑兼容低版本的浏览器就可以使用2.x
最终版本:2.2.4(2016年5月20日)
3.x:不兼容ie678,只支持最新的浏览器,除非特殊要求
一般不会使用3.x版本的,很多老的JQuery插件不支持这个版本
目前该版本是官方主要更新维护的版本
jquery xxx.js与jquery xxx.min.js的区别:
1.jquery xxx.js:开发版本,给程序员看的,有良好的缩进和注释,体积小一点
2.jquery xxx.min.js:生产版本,程序中使用,没有缩进,体积小一点,程序加载更快
- 导入JQuery的js文件:导入
min.js
文件 - 使用
var div1=$("#div1");
alert(div1.html());
1.3 JQuery对象和JS对象区别与转换
- JQuery对象在操作时,更加方便
- JQuery对象和js对象方法不通用
- 两者相互转换:
- jq—>js:
jq对象[索引]
或jq对象.get(索引)
- js—>jq:
$(js对象)
1.4 JQuery事件绑定和入口函数
**选择器:**筛选具有相似特征的元素(标签)
基本语法:
- 事件绑定:
$("").click(function (){
});
- 入口函数:
$(function (){
})//jquery入口函数(dom文档加载完成后执行该函数中的代码)
window.onload
和$(function)
区别:
-
window.onload
只能定义一次,如果定义多次,后边的会将前边的覆盖掉 -
$(function)
可以定义多次
- 样式控制:
$("#div1").css("background-color","red");
$("#div2").css("backgroundColor","pink");
第二节:JQuery选择器
2.1 基本选择器
- 标签选择器(元素选择器)
语法:$("html标签名")
获得所有匹配标签名称的元素 - id选择器
语法:$("#id"的属性值)
获得与指定id属性值匹配的元素 - 类选择器
语法:$(".class的属性值")
获得与指定的class属性值匹配的元素 - 并集选择器
语法:$("选择器1,选择器2,...")
获得多个选择器选中的所有元素
2.2 层级选择器
- 后代选择器
语法:$("A B")
选择A元素内部的所有B元素 - 子选择器
语法:$("A>B")
选择A元素内部的所有B子元素
2.3 属性选择器
- 属性名称选择器
语法:$("A[属性名]")
包含指定属性的选择器 - 属性选择器
语法:$("A[属性名='值']")
包含指定属性等于指定值的选择器
语法:$("A[属性名!='值']")
包含多个属性条件不为指定值的选择器
语法:$("A[属性名^='值']")
包含多个属性条件以"值"为开始的选择器
语法:$("A[属性名$='值']")
包含多个属性条件以"值"为结束的选择器
语法:$("A[属性名*='值']")
包含多个属性条件包含"值"的选择器 - 复合属性选择器
语法:$("A[属性名='值'][]...")
包含多个属性条件的选择器
2.4 过滤选择器
- 首元素选择器
语法::first
获得选择的元素中的第一个元素 - 尾元素选择器
语法::last
获得选择的元素中最后一个元素 - 非元素选择器
语法::not(selecter)
不包括指定内容的元素 - 偶数选择器
语法::even
偶数,从0开始计数 - 奇数选择器
语法::odd
奇数,从0开始计数 - 等于索引选择器
语法::eq(index)
指定索引元素 - 大于索引选择器
语法::gt(index)
大于指定索引元素 - 小于索引元素
语法::lt(index)
小于指定索引元素 - 标题选择器
语法::header
获取标题元素(h1-h6),固定写法
2.5 表单过滤选择器
- 可用元素选择器
语法::enabled
获得可用元素 - 不可用元素选择器
语法::disabled
获得不可用元素 - 选中选择器
语法::checked
获得单选/复选框选中的元素 - 选中选择器
语法::selected
获得下拉框选中的元素
第三节:DOM操作
3.1 内容操作
html()
:获取/设置元素的标签体内容<a><font>内容</font></a>
----><font>内容</font>
获取:$("#myinput").html();
设置:$("#myinput").html("<p>李四</p>");
text()
:获取/设置元素的标签体纯文本内容<a><font>内容</font></a>
---->内容
获取:$("#myinput").text();
设置:$("#myinput").text("李四");
val()
:获取/设置元素的value
属性值
获取:$("#myinput").val();
设置:$("#myinput").val("李四");
3.2 属性操作
- 通用属性操作
-
attr()
:获取/设置(改变、增加)元素的属性 -
removeAttr()
:删除属性 -
prop()
:获取/设置(改变、增加)元素的属性 -
removeProp()
:删除属性
attr()
和prop()
的区别?
- 如果操作的是元素的固有属性,则建议使用
prop()
- 如果操作的是元素的自定义属性,则建议使用
attr()
- 对class属性操作
addClass()
:添加class属性值removeClass()
:删除class属性值toggleClass()
:切换class属性toggleClass("one")
:判断如果元素对象上存在class=“one”,则将属性值one删除掉;如果元素对象上不存在class=“one”,则添加css()
:改变styly属性
3.3 CRUD操作
append()
:父元素将子元素追加到末尾对象1.append(对象2)
:将对象2添加到对象1内部,并且在末尾prepend()
:父元素将子元素追加到开头对象1.prepend(对象2)
:将对象2添加到对象1内部,并且在开头appendTo()
:子元素将父元素追加到末尾对象1.appendTo(对象2)
:将对象1添加到对象2,并且在末尾prependTo()
:子元素将父元素追加到开头对象1.prependTo(对象2)
:将对象1添加到对象2内部,并且在开头after()
:添加元素到元素后边对象1.after(对象2)
:将对象2添加到对象1后边,对象1和对象2是兄弟关系before()
:添加元素到元素前边对象1.before(对象2)
:将对象2添加到对象1前边,对象1和对象2是兄弟关系insertAfter()
:对象1.insertAfter(对象2)
:将对象1添加到对象2前边,对象1和对象2是兄弟关系insertBefore()
:对象1.insertBefore(对象2)
:将对象1添加到对象2后边,对象1和对象2是兄弟关系remove()
:移除元素对象.remove()
:将对象删除掉empty()
:清空元素的所有子元素(后代元素)对象.empty()
:将对象的后代元素全部清空,但是保留当前对象以及其属性节点
第四节: 动画和遍历
4.1 动画
- 默认显示和隐藏方式
show([speed,[easing],[fn]])
参数:
- **speed:**动画速度。三个预定义的值:(
"slow","normal","fast",毫秒值
) - **easing:**切换效果。默认是
swing
,可用参数:liner
swing
:动画执行时,效果是先慢中间快,最后又慢liner
:动画执行时,速度是匀速的 - **fn:**在动画完成时执行的函数,每个元素执行一次
hide([speed,[easing],[fn]])
toggle([speed],[easing],[fn])
- 滑动显示和隐藏方式
slideDown([speed],[easing],[fn])
slideUp([speed],[easing],[fn])
slideToggle([speed],[easing],[fn])
- 淡入淡出显示和隐藏方式
fadeIn([speed],[easing],[fn])
fadeOut([speed],[easing],[fn])
fadeToggle([speed,[easing],[fn]])
4.2 Jquery遍历
- js的遍历方式
for(初始化值;循环结束条件;步长)
- jq的遍历方式
jq对象.each(callback)
callback
:是function(index,element)
函数index(索引) element(元素对象)
- 如果当前function返回为false,则结束循环(break)
如果当前function返回为true,则结束本次循环(continue)
$("#city li").each(function (index,element){
alert(this.innerText)
//3.2 第二种:在回调函数中定义参数 index(索引) element(元素对象)
//如果是上海结束循环
if ("上海"===$(element).html()) {
//如果当前function返回为false,则结束循环(break)
//如果当前function返回为true,则结束本次循环(continue)
return false
}
alert(index+":"+$(element).html())
})
$.each(object,[callback])
现阶段和jq.each()
使用差不多for..of:
JQuery3.0 之后才提供的方式
for(li of $("#city li")){
alert($(li).html())
}
第五节:JQuery事件绑定和切换
5.1 事件绑定
jq对象.事件方法(回调函数);
jq常用方法:
$("#name").focus();//让文本输入框获得焦点
表单对象.submit();//让表单提交
$(function (){
//1.获取name对象,绑定click事件
$("#name").click(function (){
alert("我被点击了")
})
})
//多个绑定事件,简化操作,链式编程
$("#name").mouseover(function (){
alert("鼠标来了")
}).mouseout(function (){
alert("鼠标走了")
})
//jq独有方法
$("#name").focus();//让文本输入框获得焦点
on 用于绑定事件
off 解绑绑定事件
jq对象.on("事件名称",回调函数)
jq对象.off("事件名称")
如果off内不传递任何参数,则将组件上的所有事件全部解绑
//使用on给按钮绑定单击事件
$("#name").on("click",function (){
alert("我被点击了")
})
//使用off给按钮解除单击事件
$("#name2").on("click",function (){
//接除name单击事件
$("#name").off("click");
})
5.2 事件切换
jq对象.toggle(fn1,fn2,...)
:在jq1.9版本之后被移除了,但可以使用JQuery Migrate(迁移)插件
可以恢复使用
当单击jq对象对应的组件后,会执行fn1,再次点击执行fn2,…,之后会执行fn1,…
$(function (){
$("#click").toggle(function (){
//改变box背景色
$("#box").css("backgroundColor","blue")
},function (){
$("#box").css("backgroundColor","yellow")
},function (){
$("#box").css("backgroundColor","pink")
})
})
5.3 插件
**插件:**增强JQuery的功能
- 实现方式:
-
jQuery.fn.extend(Object)
:增强通过Jquery获取的对象的功能,$("#id")
-
jQuery.exttend(Object)
:增强JQuery对象自身的功能,$/jQuery
$fn.extend({
//定义了一个check()方法,所有的jq对象都可以调用该方法
check:function(){
//...
},
uncheck:function(){
//...
}
})
//调用
$("#btn-check").click(function(){
//获取复选框对象
$("#input[type='checked']").check();
})
$.extend({
max:function(a,b){
return a>=b?a:b;
}
min:function(a,b){
return a<=b?a:b;
}
})
//调用全局方法
var max=$.max(2,3);
alert(max)