第四章:Request和Response

第一节:Request与Response原理和继承体系

1.1 Request对象和Response对象原理
  1. request和response对象是由服务器创建的,我们只是来使用它们而已
  2. request对象是来获取请求消息的response对象是来设置响应消息的

附件接口java_java

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

方法:

  1. 获取请求方式:GET
    String getMethod()
  2. 获取虚拟目录:/day14
    String getContextPath()
  3. 获取Servlet路径:/demo01
    String getServletPath()
  4. 获取GET方式的请求参数:name=zhangsan
    String getQueryString()
  5. 获取请求的URI:/day14/demo01
    String getRequestURI():/day14/demo01
    String getRequsetURL():http://localhost/day14/demo01
  6. 获取协议及版本号:HTTP/1.1
    String getProtocol()
  7. 获取客户机的IP地址:
    String getRemoteAddr()
2、获取请求头数据

方法:

  1. 通过请求头的名称获取头的值
    String getHeader(String name)
  2. 获取所有的请求头名称
    Enumeration<String> getHeaderNames()Enumeration<String>:枚举接口,可以理解为迭代器,把它当作迭代器使用
3、获取请求体数据

**请求体:**只有post请求方式,才有请求体,在请求体中封装了post请求的请求参数

步骤:

  1. 获取流对象
    BufferedReader getReader():获取字符输入流,只能操作字符数据
    ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
  2. 再从流对象中拿数据
2.2 其他功能
1、获取请求参数通用方式

不论post还是get都能使用下列方法

  1. String getParameter(String name)根据参数名称获取参数值
  2. String[] getParamaterValues(String name)根据参数名称获取参数值的数组
  3. Enumeration<String> getParameterNames()获取所有请求的参数名称
  4. Map<String,String[]> getParameterMap()获取所有参数的map集合
2、请求转发

**请求转发:**一种在服务器内部的资源跳转方式

  1. 步骤:
  1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
  2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
  1. 特点:
  1. 浏览器地址栏路径没有发生变化
  2. 只能转发到当前的服务器内部资源中
  3. 转发是一次请求
3、共享数据

**域对象:**一个有作用范围的对象,可以在范围内共享数据

**request域:**代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:

  1. viod setAttribute(String name,Object obj):存储数据
  2. Object getAttribute(String name):通过键获取值
  3. void removeAttribute(String name):通过键移除键值对
4、获取ServletContext
  1. ServletContext getServletContext():获取ServletContext
2.3 中文乱码问题

**get方式:**tomcat 8 已经将get方式乱码问题解决了

**post方式:**会乱码

**解决:**在获取参数前,设置request的编码

request.setCharacterEncoding("utf-8");

第三节:案例-用户登录

用户登陆案例需求:
  1. 编写login.html登陆界面
  2. 使用Druid数据库连接池技术,操作mysql,all中userlogin表
  3. 使用JDBCTemplate技术封装JDBC
  4. 登陆成功跳转到SuccessServlet展示:登陆成功!用户名欢迎您
  5. 登陆失败跳转到FFailServlet展示:登陆失败,用户名或密码错误
开发步骤:
  1. 创建项目,导入html页面配置文件与jar包
  2. 创建数据库的环境
  3. 创建实体类
  4. 创建UserDao类,提供login()方法
  5. 创建类UserDao2,提供login方法
  6. 创建LoginServlet2类
  7. form表单的action写法:虚拟目录+Servlet的资源路径
  8. BeanUtils工具类,简化数据封装
3.2 BeanUtils介绍

BeanUtils工具类:简化数据封装

  1. JavaBean:标准的Java类
  1. 要求:
  1. 类必须被public修饰
  2. 必须提供空参的构造方法
  3. 成员变量必须使用private修饰
  4. 提供公共setter和getter方法
  1. 功能:封装数据
  1. 概念:
  1. 成员变量
  2. 属性:setter和getter方法截取后的产物
    例如:getUsername()---->Useername---->username
  1. 方法
  1. setProperty()
  2. getProperty()
  3. populate(Object,Map):将Map集合的键值对信息,封装到对应的JavaBean对象中

第四节:HTTP响应协议

4.1 概述

**请求消息:**客户端发送给服务器端的数据

  • 数据格式:
  1. 请求行
  2. 请求头
  3. 请求空行
  4. 请求体

**响应消息:**服务器端发送给客户端的数据

  • 数据格式:
  1. 响应行
  1. 组成:协议/版本 响应状态码 状态码描述
  2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
  1. 状态码都是三位数字
  2. 分类:
  1. 1xx:服务器接收客户端消息但没有接收完成,等待一段时间后,发送1xx状态码
  2. 2xx:成功。代表:200
  3. 3xx:重定向。代表:302(重定向) 304(访问缓存)
  4. 4xx:客户端错误。
    代表:404(请求路径没有对应的资源)
    405(请求方式没有对应的doxx方法)
  5. 5xx:服务器端错误。代表:500(服务器内部出现异常)
  1. 响应头
  1. 格式:头名称:值
  2. 常见的响应头:
  1. Content-Type:服务器告诉客户端本次的响应消息体数据格式以及编码格式
  2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
    值:
  1. in-line:默认值,在当前页面内打开
  2. attachment;filename=xxx:以附件形式打开响应体。文件下载
  1. 响应空行
  2. 响应体:真实的传输的数据
  • 响应的字符串格式:
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功能

功能:设置响应消息

  1. 设置响应行
  1. 格式:HTTP/1.1 200 ok
  2. 设置状态码:setStatus(int sc)
  1. 设置响应头
    setHeader(String name,String value)
  2. 设置响应体
    使用步骤:
  1. 获取输出流
  1. 字符输出流:PrintWriter getWriter()
  2. 字节输出流:ServletOutputStream getOutputStream()
  1. 使用数据流,将数据输出到客户端浏览器
5.2 案例
  1. 完成重定向
  1. **重定向:**资源跳转的方式
  2. 代码实现
    setHeader(String name,String value)sendRedirect(String value)
  3. 重定向(redirect)的特点
  1. 地址栏发生变化
  2. 重定向可以访问其他站点(服务器)的资源
  3. 重定向是两次请求,不能使用request共享数据

转发(forward)的特点:

  1. 转发地址栏路径不变
  2. 转发只能访问当前服务器下的资源
  3. 转发是一次请求,可以使用request对象共享资源
  1. 路径写法
  1. 服务器输出字符数据到浏览器
    步骤:
  1. 获取字符输出流
    ServletOutputStream sos=resp.getOutputStream();
  2. 输出数据
    sos.write("你好".getBytes("utf-8"));

注意:

乱码问题:

  1. PrintWriter pw=resp.getWriter();获取的流默认编码是ISO-8859-1的
  2. 设置该流的默认编码
  3. 告诉浏览器响应体使用的编码
    简单的形式(在获取流之前):resp.setContentType("text/html;charset=utf-8");复杂的形式:resp.setHeader("content-type","text/html;charset=utf-8");
  1. 服务器输出字节数据到浏览器
  2. 验证码
  1. 实质:是一张图片
  2. 目的:防止恶意表单注册
5.3 路径
相对路径

通过相对路径不可以确定唯一资源

如:./index.html

不以/开头,以.开头的路径

**规则:**找到当前资源和目标资源之间的相对位置关系

**./😗*当前目录

…/:后退一级目录

绝对路径

通过绝对路径可以确定唯一资源

如:http://localhost/day15/responseDemo02可以省略为:/day15/responseDemo02

以/开头的路径

**规则:**判断定义的路径是给谁用的(判断请求将来从哪发出)

  1. 给客户端浏览器:需要加虚拟目录(项目的访问路径)
    建议虚拟目录动态获取:request.getContextPath()<a>,<form>,重定向...
  2. 给服务器:不需要加虚拟目录
    转发路径
5.4 ServletContext对象
  1. **概念:**代表整个web应用,可以和程序的容器(服务器)来通信
  2. 获取:
  1. 通过request对象来获取
    request.getServletContext();
  2. 通过httpServlet获取
    this.getServletContext();
  1. 功能:
  1. 获取MIME类型:
    MIME类型:在互联网通信过程中定义的一种文件数据类型
    格式:大类型/小类型 text/html image/jpeg
    获取:String getMimeType(String file)
  2. 域对象:共享数据
  1. setAttribute(String name,Object value)
  2. getAttribute(String name)
  3. removeAttribute(String name)**ServletContext对象范围:**所有用户所有请求的数据
  1. 获取文件的真实路径(服务器路径)
  1. 方法:String getRealPath(String path)
5.5 文件下载案例

文件下载需求:

  1. 页面显示超链接
  2. 点击超链接后弹出下载提示框
  3. 完成图片文件的下载

分析:

  1. 超链接指向的资源如果能被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
  2. 任何资源都必须弹出下载提示框
  3. 任何响应头设置资源的打开方式:
    content-disposition:attachment;filename-xxx

步骤:

  1. 定义页面,编辑超链接href属性,指向Servlet,传递资源的名称filename
  2. 定义Servlet
  1. 获取文件的名称
  2. 使用字节输入流加载文件进内存
  3. 指定responese的响应头:content-disposition:attachment;filename-xxx
  4. 将数据写出到response输出流

问题:

中文文件问题:

解决思路:

  1. 获取客户端使用的浏览器版本信息
  2. 根据不同的版本信息,设置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 会话技术

**会话:**一次会话中包含多次请求和响应

**一次会话:**浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止

**会话功能:**在一次会话的范围内的多次请求间共享资源

方式:

  1. 客户端会话技术:Cookie
  2. 服务器端会话技术:Session
1.2 Cookie快速入门
  1. **概念:**客户端会话技术,将数据保存到客户端
  2. 使用步骤:
  1. 创建Cookie对象,绑定数据
    new Cookie(String name,String value)
  2. 发送Cookie对象
    response.addCookie(Cookie cookie)
  3. 获取Cookie,拿到数据
    Cookie[] request.getCookies()
  1. 实现原理:
  2. Cookie的细节
  1. 一次可不可以发送多个Cookie?
    可以创建多个Cookie对象,使用response调用多次addCookie()方法发送Cookie即可
  2. Cookie在浏览器中保存多长时间?
  1. 默认情况下,当浏览器关闭后,Cookie数据被销毁
  2. 设置Cookie的生命周期,使它持久化存储
    setMaxAge(int seconds)
  1. 正数:持久化将Cookie数据写入到硬盘文件中,持久化存储。也是Cookie的存活时间
  2. 负数:默认值,当浏览器关闭后,Cookie数据被销毁
  3. 0:删除Cookie信息
  1. Cookie能不能存中文?
  1. 在tomcat 8之前,Cookie中不能直接存储中文数据
    需要将中文数据转码----一般采用URL编码(%E3)
    URLEncoder.encode(lastTime,"utf-8");
  2. 在tomcat 8之后,Cookie支持中文数据.但对特殊字符还是不支持,建议使用URL编码存储,再用URL进行解码取出
    URLDecoder.decode(lastTime,"utf-8")
  1. Cookie共享问题?
  1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中Cookie能不能共享
    默认情况下,Cookie不能共享
    setPath(String path):设置Cookie的获取范围。默认情况下,会设置当前的虚拟目录
    如果要共享,则可以将path设置为"/"
  2. 不同的tomcat服务器间Cookie共享问题
    setDomain(String path):如果设置一级域名相同,那么多个服务器之间Cookie可以共享
    setDomain(".baidu.com"),那么tieba.baidu.comnews.baidu.com中,Cookie可以共享
Cookie的特点和作用
  1. Cookie存储数据在客户端浏览器
  2. 浏览器对于单个Cookie的大小(4kb)有限制以及对同一个域名下的总Cookie数量(20个)也有限制

作用:

  1. Cookie一般用于存储少量的不太敏感的数据
  2. 在不登陆的情况下,完成服务器对客户端的身份识别
  1. **案例:**记住上一次访问时间
  1. 需求:
  1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
  2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
  1. 分析:
  1. 可以采用Cookie来完成
  2. 在服务器中的Servlet判断是否有一个名为lastTime的Cookie
  1. 有:不是第一次访问
  1. 欢迎回来,您上次访问时间为:。。。
  2. 写回Cookie
  1. 没有:是第一次访问
  1. 响应数据:您好,欢迎您首次访问
  2. 写回Cookie:lastTime=。。。

第二节:JSP入门学习

2.1 概念

**Java Server Pages:**Java服务器端页面,可理解为一个特殊的页面,其中即可以直接定义HTML的标签,又可以定义Java代码,用于简化书写

2.2 JSP原理

JSP本质上就是一个Servlet

附件接口java_附件接口java_02

2.3 JSP脚本

**JSP脚本:**JSP定义Java代码的方式

  1. <% Java代码 %>:定义的Java代码在service方法中。service方法中可以定义什么,该脚本中就可以定义什么
  2. <%! Java代码 %>:定义的Java代码,在JSP转换后的Java类成员位置
  3. <%= 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的

附件接口java_java_03

3.4 Session细节
  1. 当客户端关闭后,服务器不关闭,两次获取session不是同一个
    默认情况下:不是
    如果需要相同,则可以创建Cookie,Cookie的键为JSESSIONID,设置最大存活时间,让Cookie持久化保存
Cookie cookie=new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60*60);
response.addCookie(cookie);
  1. 客户端不关闭,服务器关闭后,两次获取的session不是同一个
    虽然session对象不是同一个,但是要确保数据不丢失
  • **session的钝化:**在服务器正常关闭之前,将session对象系列化到硬盘上
  • **session的活化:**在服务器启动后,将session文件转化为内存中的session对象即可
  1. Session什么时候被销毁
  1. 服务器关闭
  2. session对象调用void invalidate()方法,自己销毁自己
  3. session默认失效时间为30分钟
    选择性的配置修改:在web.xml文件下找到:
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
  1. session的特点
  1. session用于存储一次会话的多次请求的数据,存在服务器端
  2. session可以存储任意类型、任意大小的数据
  1. session与cookie的区别:
  1. session存储在服务器端,cookie存储在客户端
  2. session没有数据大小限制,cookie有大小限制
  3. session数据安全,cookie数据相对不安全
3.5 案例:验证码
案例需求:
1.访问带有验证码的登录页面login.html
2.用户输入验证码、密码以及用户名
    如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
    如果验证码输入有误,跳转登录页面,提示:验证码错误
    如果全部正确,则跳转到主页success.jsp,显示:用户名,欢迎您
分析:

附件接口java_笔记_04

第四章:JSP,EL和JSTL

4.1 JSP基础语法
  1. 指令
    **作用:**用于配置JSP页面,导入资源页面
    格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>分类:
  1. **page:**配置JSP页面的
  • contentType:等同于response.setContentType()
  1. 设置响应体的mime类型以及字符集
  2. 设置当前JSP页面的编码(只能是高级的开发工具才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集编码)
  • language:现在只能写Java
  • buffer:缓冲区的大小,默认为8kb
  • **import:**导包
  • errorPage:当前页面发生异常后会自动跳转到指定页面
  • isErrorPage:标识当前页面是否是错误页面
  • **true:**是,可以使用内置对象execption
  • **false:**否。默认值,不可以使用内置对象execption
  1. **include:**页面包含的。导入页面的资源文件
    <%@ include file="文件名"%>
  2. **taglib:**导入资源
    <%@taglib prefix="" uri="" %> **prefix:**前缀,自定义的
  1. 注释
  1. html注释:
    <!-- -->:只能注释html代码片段
  2. JSP注释:
    <%-- --%>:可以注释所有,且不能通过浏览器response查看注释。推荐使用此注释
  1. 内置对象:在jsp页面中不需要创建,直接使用的对象

变量名

真实类型

作用

pageContext

PageContext

当前页面共享数据,还可以获取其它八个内置对象

request

HttpServletRequest

一次请求访问的多个资源(转发)

session

HttpSession

一次会话的多个请求间

application

ServletContext

所有用户间共享数据

response

HttpServletResponse

响应对象

page

Object

当前页面(Servlet)的对象

out

JspWriter

输出对象,可以把数据输出到页面上

config

ServletConfig

Servlet的配置对象

execption

Throwable

异常对象

4.2 MVC开发模式
  1. JSP演变历史
  1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
  2. 后来有jap,简化了Servlet的开发,如果过度使用jsp,在jsp中既写大量的Java代码,又写html表,造成难以维护,难以分工协作
  3. 再后来,Javaweb开发借鉴mvc开发模式,使得程序的设计更加合理性
  1. MVC
  1. M:Model,模型。JavaBean完成具体的业务操作,如:查询数据库,封装对象
  2. V:View,视图。JSP展示数据
  3. C:Controller,控制器。Servlet
  1. 获取用户的输入
  2. 调用模型
  3. 将数据交给视图进行展示

附件接口java_笔记_05

  1. 优点:
  1. 耦合性低,方便维护,可以利于分工协作
  2. 重用性高
  3. 生命周期成本低
  4. 部署快
  5. 可维护性高
  6. 有利于软件工程管理
  1. 缺点:
    使得项目架构变得复杂,对开发人员要求高很多
4.3 EL表达式
  1. **概念:**Expression Language 表达式语言
  2. **作用:**替换和简化jsp页面中Java代码的编写
  3. 语法:${表达式}
  4. 注意:
    jsp默认支持EL表达式
    如果要忽略EL表达式:
  1. 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
  2. \${表达式}:忽略当前这个el表达式
  1. 使用:
  1. 运算
    运算符:
  1. 算数运算符:+ - * /(div) %(mod)
  2. 比较运算符:> < <= >= == !=
  3. 逻辑运算符:&&(and) ||(or) !(not)
  4. 空运算符:empty功能:用于判断字符串、集合、数组对象是否为null并且长度是否为0
    ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
    ${not empty str}:表示判断字符串、集合、数组对象是否不为null,并且长度>0
  1. 获取值
  1. el表达式只能从域对象中获取值
  2. 语法:
  1. ${域名称.键名}:从指定域中获取指定键的值
    域名称:
  1. pageScore--->pageContext
  2. requestScope----->request
  3. sessionScope------>session
  4. applicationScope------->application(ServletContext)

举例:在request域中存储了name=张三

获取:${requsetScope.name}

  1. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止
  2. 获取对象、List集合、Map集合的值
  1. 对象:${域名称.键名.属性名}本质上会去调用对象的getter方法
  2. List集合:${域名称.键名[索引]}
  3. Map集合:${域名称.键名.key名称}${域名称.键名["key名称"]}
  1. 隐式对象
    EL表达式中有11个隐式对象
    pageContext
  1. 获取jsp其他八个内置对象:${pageContext.request.contextPath}:动态获取虚拟目录
4.4 JSTL常用标签
  1. 概念:JavaServer Pages Tag Library JSP标准标签库
    是由Apache组织提供的开源的免费的jsp标签
  2. **作用:**用于简化和替换jsp页面上的Java代码
  3. 使用步骤:
  1. 导入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包
  1. 引入标签库:taglib指令:<%@ taglib %>
  2. 使用标签
  1. 常用的JSTL标签:
  1. **if:**相当于Java代码的if语句
  1. 属性:
  1. test是必须属性,接收boolean表达式
  2. 若boolean表达式为true,则显示标签体内容,若boolean表达式为false,则不显示标签体内容
  3. 一般情况下,test属性值会结合el表达式一起使用
  1. 注意:c:if标签没有else情况,想要else情况则可以再定义一个c:if标签
  1. choose:相当于Java代码的switch语句
  1. 使用choose标签声明 相当于switch声明
  2. 使用when标签做判断 相当于case
  3. 使用otherwise标签做其他情况的声明 相当于default
  1. foreach:相当于Java代码的for语句
  1. 完成重复的操作
  • 属性:begin:开始值
    end:结束值
    var:临时变量
    step:步长
    varStatus:循环状态对象
    index:容器中元素的索引,从0开始
    count:循环次数,从1开始
  1. 遍历容器
  • 属性:items:容器对象
    var:容器中元素的临时变量
    varStatus:循环状态对象

index:容器中元素的索引,从0开始

count:循环次数,从1开始

  1. 练习:
    需求:在request域中存有User对象的list集合,需要使用jstl+el将list集合数据展示到jsp页面中的表格table中
4.5 综合案例

综合练习:

  1. 简单功能
  1. 列表查询
  2. 登录
  3. 添加
  4. 删除
  5. 修改
  1. 复杂功能
  1. 删除选中
  2. 分页查询
  3. 复杂条件查询

第五章:Filter和Listener

5.1 Filter概述

生活中的过滤器:纯净器、空气净化器、土匪

**web中的过滤器:**当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能

**过滤器的作用:**一般用于完成通用的操作,如登录验证、统一编码处理、敏感字符过滤…

5.2 Filter快速入门
  1. 步骤:
  1. 定义一个类,实现接口Filter
  2. 复写方法
  3. 配置拦截路径
  1. web.xml
  2. 注解配置:urlPatterns = "/被拦截的文件路径"
5.3 Filter细节
  1. 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>
  1. 过滤器执行流程
  1. 执行过滤器
  2. 执行放行后的资源
  3. 回来执行过滤器放行代码下的代码
  1. 过滤器生命周期方法
  1. init():在服务器启动后,会创建Filter对象,然后调用init方法,只执行一次。用于加载资源
  2. destroy():在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法,只执行一次,用于释放资源
  3. doFilter():每一次请求被拦截资源时,会执行,执行多次
  1. 过滤器配置详解
  1. 拦截路径配置:
  1. 具体资源路径:/index.jsp:只有访问index.jsp时,过滤器才会被执行
  2. 目录拦截:/user/*:访问/user下的所有资源时,过滤器都会被执行
  3. 后缀名拦截:*.jsp:访问所有jsp资源时,过滤器都会被执行
  4. 拦截所有资源:/*:访问所有资源时,过滤器都会被执行
  1. 拦截方式配置:资源被访问的方式
  1. 注解配置:
  • 设置dispatcherTypes属性,取值为:
  1. DispatcherType.REQUEST:默认值,浏览器直接请求资源
  2. DispatcherType.FORWARD:转发来访问资源
  3. DispatcherType.INCLUDE:包含访问资源
  4. DispatcherType.ERROR:错误跳转资源
  5. DispatcherType.ASYNC:异步访问资源
  1. web.xml配置:
  • 设置<dispatcher></dispatcher>标签即可
  1. REQUEST:默认值,浏览器直接请求资源
  2. FORWARD:转发来访问资源
  3. INCLUDE:包含访问资源
  4. ERROR:错误跳转资源
  5. ASYNC:异步访问资源
  1. 过滤器链(配置多个过滤器)
  • 执行顺序:如果有两个过滤器:过滤器1和过滤器2
  1. 过滤器1
  2. 过滤器2
  3. 资源执行
  4. 过滤器2
  5. 过滤器1
  • 先后顺序问题:
  1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
    如:AFilterBFilterAFilter就先执行了
  2. web.xml配置:<filter-mapping>谁定义在上边,谁先执行
5.4 案例
  1. 登录验证:
需求:
    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. 敏感词汇过滤:
需求:
    1.对案例录入的数据进行敏感词汇过滤
    2.敏感词汇参考(敏感词汇.txt)
    3.如果是敏感词汇,替换为***
分析:
    1.对request对象进行增强。增强获取参数相关方法
    2.放行。c

增强对象的功能:

  • 设计模式:一些通用的解决固定问题的方式
  1. 装饰模式:
  2. 代理模式:
  • 概念:
  1. 真实对象:被代理的对象
  2. 代理对象
  3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
  • 实现方式:
  1. 静态代理:在有一个类文件描述代理模式
  2. 动态代理:在内存中形成代理类
    实现步骤:
  1. 代理对象和真实对象实现相同的接口
  2. 获取代理对象Proxy.newProxyInstance()
  3. 使用代理对象调用方法
  4. 增强方法

方法参数:

invoke(Object proxy, Method method, Object[] args)

  1. proxy:代理对象
  2. method:代理对象调用的方法,被封装为的对象
  3. args:代理对象调用方法时,传递的实际参数

增强方式:

  1. 增强参数列表
  2. 增强返回值类型
  3. 增强方法体执行逻辑
5.5 Listener:监听器

**概念:**web的三大组件之一

  • 事件监听机制
  • 事件 :一件事情
  • 事件源:事件发生的地方
  • 监听器:一个对象
  • 注册监听:将事件、事件源、监听器绑定在一起。当事件源发生某个事件后,执行监听器代码
  • servletContextListener:监听SerletContext对象的创建和替换
  • 方法:

void contextDestroyed(ServletContextEvent sce):SerletContext对象被销毁之前会调用该方法

void contextInitialized(ServletContextEvent sce):SerletContext对象创建后会调用该方法

  • 步骤:
  1. 定义一个类,实现servletContextListener接口
  2. 复写方法
  3. 配置
  1. 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 快速入门
  1. 步骤:
  1. 下载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:生产版本,程序中使用,没有缩进,体积小一点,程序加载更快
  1. 导入JQuery的js文件:导入min.js文件
  2. 使用
var div1=$("#div1");
alert(div1.html());
1.3 JQuery对象和JS对象区别与转换
  1. JQuery对象在操作时,更加方便
  2. JQuery对象和js对象方法不通用
  3. 两者相互转换:
  1. jq—>js: jq对象[索引]jq对象.get(索引)
  2. js—>jq: $(js对象)
1.4 JQuery事件绑定和入口函数

**选择器:**筛选具有相似特征的元素(标签)

基本语法:

  1. 事件绑定:
$("").click(function (){
    
});
  1. 入口函数:
$(function (){
    
})//jquery入口函数(dom文档加载完成后执行该函数中的代码)

window.onload$(function)区别:

  • window.onload只能定义一次,如果定义多次,后边的会将前边的覆盖掉
  • $(function)可以定义多次
  1. 样式控制:
  1. $("#div1").css("background-color","red");
  2. $("#div2").css("backgroundColor","pink");

第二节:JQuery选择器

2.1 基本选择器
  1. 标签选择器(元素选择器)
    语法:$("html标签名") 获得所有匹配标签名称的元素
  2. id选择器
    语法:$("#id"的属性值) 获得与指定id属性值匹配的元素
  3. 类选择器
    语法:$(".class的属性值") 获得与指定的class属性值匹配的元素
  4. 并集选择器
    语法:$("选择器1,选择器2,...") 获得多个选择器选中的所有元素
2.2 层级选择器
  1. 后代选择器
    语法:$("A B") 选择A元素内部的所有B元素
  2. 子选择器
    语法:$("A>B") 选择A元素内部的所有B子元素
2.3 属性选择器
  1. 属性名称选择器
    语法:$("A[属性名]") 包含指定属性的选择器
  2. 属性选择器
    语法:$("A[属性名='值']") 包含指定属性等于指定值的选择器
    语法:$("A[属性名!='值']") 包含多个属性条件不为指定值的选择器
    语法:$("A[属性名^='值']") 包含多个属性条件以"值"为开始的选择器
    语法:$("A[属性名$='值']") 包含多个属性条件以"值"为结束的选择器
    语法:$("A[属性名*='值']") 包含多个属性条件包含"值"的选择器
  3. 复合属性选择器
    语法:$("A[属性名='值'][]...") 包含多个属性条件的选择器
2.4 过滤选择器
  1. 首元素选择器
    语法::first 获得选择的元素中的第一个元素
  2. 尾元素选择器
    语法::last 获得选择的元素中最后一个元素
  3. 非元素选择器
    语法::not(selecter) 不包括指定内容的元素
  4. 偶数选择器
    语法::even 偶数,从0开始计数
  5. 奇数选择器
    语法::odd 奇数,从0开始计数
  6. 等于索引选择器
    语法::eq(index) 指定索引元素
  7. 大于索引选择器
    语法::gt(index) 大于指定索引元素
  8. 小于索引元素
    语法::lt(index) 小于指定索引元素
  9. 标题选择器
    语法::header 获取标题元素(h1-h6),固定写法
2.5 表单过滤选择器
  1. 可用元素选择器
    语法::enabled 获得可用元素
  2. 不可用元素选择器
    语法::disabled 获得不可用元素
  3. 选中选择器
    语法::checked 获得单选/复选框选中的元素
  4. 选中选择器
    语法::selected 获得下拉框选中的元素

第三节:DOM操作

3.1 内容操作
  1. html():获取/设置元素的标签体内容 <a><font>内容</font></a>----><font>内容</font>获取:$("#myinput").html();设置:$("#myinput").html("<p>李四</p>");
  2. text():获取/设置元素的标签体纯文本内容 <a><font>内容</font></a>---->内容获取:$("#myinput").text();设置:$("#myinput").text("李四");
  3. val():获取/设置元素的value属性值
    获取:$("#myinput").val();设置:$("#myinput").val("李四");
3.2 属性操作
  1. 通用属性操作
  1. attr():获取/设置(改变、增加)元素的属性
  2. removeAttr():删除属性
  3. prop():获取/设置(改变、增加)元素的属性
  4. removeProp():删除属性

attr()prop()的区别?

  1. 如果操作的是元素的固有属性,则建议使用prop()
  2. 如果操作的是元素的自定义属性,则建议使用attr()
  1. 对class属性操作
  1. addClass():添加class属性值
  2. removeClass():删除class属性值
  3. toggleClass():切换class属性
    toggleClass("one"):判断如果元素对象上存在class=“one”,则将属性值one删除掉;如果元素对象上不存在class=“one”,则添加
  4. css():改变styly属性
3.3 CRUD操作
  1. append():父元素将子元素追加到末尾
    对象1.append(对象2):将对象2添加到对象1内部,并且在末尾
  2. prepend():父元素将子元素追加到开头
    对象1.prepend(对象2):将对象2添加到对象1内部,并且在开头
  3. appendTo():子元素将父元素追加到末尾
    对象1.appendTo(对象2):将对象1添加到对象2,并且在末尾
  4. prependTo():子元素将父元素追加到开头
    对象1.prependTo(对象2):将对象1添加到对象2内部,并且在开头
  5. after():添加元素到元素后边
    对象1.after(对象2):将对象2添加到对象1后边,对象1和对象2是兄弟关系
  6. before():添加元素到元素前边
    对象1.before(对象2):将对象2添加到对象1前边,对象1和对象2是兄弟关系
  7. insertAfter()
    对象1.insertAfter(对象2):将对象1添加到对象2前边,对象1和对象2是兄弟关系
  8. insertBefore()
    对象1.insertBefore(对象2):将对象1添加到对象2后边,对象1和对象2是兄弟关系
  9. remove():移除元素
    对象.remove():将对象删除掉
  10. empty():清空元素的所有子元素(后代元素)
    对象.empty():将对象的后代元素全部清空,但是保留当前对象以及其属性节点

第四节: 动画和遍历

4.1 动画
  1. 默认显示和隐藏方式
  1. show([speed,[easing],[fn]])参数:
  1. **speed:**动画速度。三个预定义的值:("slow","normal","fast",毫秒值
  2. **easing:**切换效果。默认是swing,可用参数:linerswing:动画执行时,效果是先慢中间快,最后又慢
    liner:动画执行时,速度是匀速的
  3. **fn:**在动画完成时执行的函数,每个元素执行一次
  1. hide([speed,[easing],[fn]])
  2. toggle([speed],[easing],[fn])
  1. 滑动显示和隐藏方式
  1. slideDown([speed],[easing],[fn])
  2. slideUp([speed],[easing],[fn])
  3. slideToggle([speed],[easing],[fn])
  1. 淡入淡出显示和隐藏方式
  1. fadeIn([speed],[easing],[fn])
  2. fadeOut([speed],[easing],[fn])
  3. fadeToggle([speed,[easing],[fn]])
4.2 Jquery遍历
  1. js的遍历方式
    for(初始化值;循环结束条件;步长)
  2. jq的遍历方式
  1. jq对象.each(callback)
  1. callback:是function(index,element)函数
  2. index(索引) element(元素对象)
  3. 如果当前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())
})
  1. $.each(object,[callback])现阶段和jq.each()使用差不多
  2. for..of:JQuery3.0 之后才提供的方式
for(li of $("#city li")){
    alert($(li).html())
}

第五节:JQuery事件绑定和切换

5.1 事件绑定
  1. jq对象.事件方法(回调函数);jq常用方法:
  1. $("#name").focus();//让文本输入框获得焦点
  2. 表单对象.submit();//让表单提交
$(function (){
	//1.获取name对象,绑定click事件
	$("#name").click(function (){
	alert("我被点击了")
	})
})
//多个绑定事件,简化操作,链式编程
$("#name").mouseover(function (){
  alert("鼠标来了")
}).mouseout(function (){
  alert("鼠标走了")
})
//jq独有方法
$("#name").focus();//让文本输入框获得焦点
  1. 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的功能

  1. 实现方式:
  1. jQuery.fn.extend(Object):增强通过Jquery获取的对象的功能,$("#id")
  2. 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)