JavaWeb知识整合

标签: Java  Web  java  web

软件开发体系架构

  • C/S结构:客户端/服务器

    优点: 有一部分代码写在客户端,用户体验比较好

    缺点:服务器更新,客户端也要随着更新,占用资源大

  • B/S结构:浏览器/服务器

    优点:客户端只要有浏览器就可以了,占用资源小,不用更新.

    缺点:用户体验不佳.

Web通信机制:基于请求响应的机制。一次请求,一次响应。

应用技术

客户端技术:html、css、js、jquery、bootstrap、easyui…

Tomcat

  1. 目录结构

    bin:可执行的文件
    conf:配置文件
    lib:jar包
    logs:日志文件
    temp:临时文件
    webapps:项目部署后的class文件
    work:jsp页面生成的文件

  2. Tomcat安装

    1. 直接解压,然后找到bin/startup.bat
    2. 可以安装
    3. 驱动之后,如果能正常看到黑窗口,表明已经安装成功.为了确保万无一失,最好在浏览器的地址栏输入:http://localhost:8080 ,如果有看到内容就代表成功了.
    4. 如果一闪而过,则是jdk环境变量没有配置

Servlet

一个运行在我们的Web服务器上,用于接收和响应客户端发来的请求,处理业务逻辑的Java程序。

  • Hello Servlet编写

    1. 编写一个类

      • 继承HttpServlet
      • 重写doGet或doPost方法
    2. 编写配置文件web.xml

      • 注册Servlet
      • 绑定路径
    3. 通过ip访问

      http://主机:端口号/项目名称/路径

    web.xml中配置文件的写法:

    <servlet>
        <servlet-name>别名</servlet-name>
        <servlet-class>全类名</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>别名</servlet-name>
        <url-pattern>需要Servlet处理的请求地址</url-pattern>
     </servlet-mapping>
    
  • 常见错误

    • 404路径不正常
    • 405找不到service方法
    • 500系统出错

**# Get/Post请求

区别:

  • GET产生一个TCP数据包;POST产生两个TCP数据包。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

  • duiGET在浏览器回退时是无害的,而POST会再次提交请求。

  • GET产生的URL地址可以被Bookmark,而POST不可以。

  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。

  • GET请求只能进行url编码,而POST支持多种编码方式。

  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

  • GET请求在URL中传送的参数是有长度限制的,而POST没有。

  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

  • GET参数通过URL传递,POST放在Request body中。

GET和POST请求的区别

Request

作用:获取浏览器发过来的数据

Request

  • String getMethod():获取请求方式
  • String getRemoteAddr():获取ip地址
  • String getContextPath() :在java中获取项目名称
  • String getRequestURI():获取的是 从项目名到参数之前的内容
  • String getServletPath():返回Servlet路径
  • StringBuffer getRequestURL():获取的带协议的完整路径
  • String getQueryString():get请求的所有参数
  • String getProtocol():获取协议和版本
  • Strig getParameter(String key):获取一个值
  • String[] getParameterValues(String key):通过一个key获取多个值
  • String getHeader(String key):通过请求头key获取指定的value(一个)
  • Enumeration getHeaders(String name) :通过key获取指定的value(多个)
  • Enumeration getHeaderNames() :获取所有的请求头的名称

中文乱码

对于get请求:参数追加到地址栏,会使用utf-8编码,服务器(tomcat7)接受到请求之后,使用iso-8859-1解码,所以会出现乱码。

对于post请求,参数是放在请求体中,服务器获取请求体的时候使用iso-8859-1解码,也会出现乱码。

解决方案:

  • 通用方案

    new String(参数.getBytes(“iso-8859-1”),“utf-8”);

  • 针对于post请求来说:只需要将请求流的编码设置成utf-8即可

    request.setCharacterEncoding(“utf-8”);

  • 修改server.xml

    <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

Response

作用:往浏览器写东西

  • setHeader():设置响应头信息

    response.setHeader(“content-type”, “text/html;charset=utf-8”):设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);
    response.setHeader(“Refresh”,”5; URL=http://www.ychs168.com“ ):5秒后自动跳转到英才科技主页。

  • response.setContentType(“text/html;charset=utf-8”):等同与调用response.setHeader(“content-type”, “text/html;charset=utf-8”);

  • response.setCharacterEncoding(“utf-8”):设置字符响应流的字符编码为utf-8;

  • response.setStatus(200):设置状态码;

  • response.sendError(404, “您要查找的资源不存在”):当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。

重定向

重定向是客户端通过一个路径访问服务器,服务器通知浏览器去访问另一个地址,浏览器再发出另一个地址的请求。

第一步:设置响应码为302

第二步:设置新请求的URL

		//设置响应码为302,表示重定向
        response.setStatus(302);
        //设置新请求的URL
        response.setHeader("Location", "http://www.ychs168.com");

便捷实现:

response.sendRedirect("http://www.ychs168.com");

response.sendRedirect()方法会设置响应头为302,以设置Location响应头。

总结:

  • 重定向是两次请求
  • 重定向的URL可以是其他服务器的应用,不局限于当前服务器。
  • 重定向的响应头为302,并且必须要有Location响应头。
  • 重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常。

转发和重定向的区别:

  1. 转发的地址栏是不变的,重定向的地址栏发生变化的。
  2. 转发是一次请求一次响应,重定向是两次请求两次响应。
  3. 转发的路径不需要加工程名,重定向的路径需要加工程名。
  4. request域对象存取的值在转发中是有效的,在重定向中是无效的。

HTTP协议(HyperText Transfer Protocol,超文本传输协议)

什么是协议 ?

双方在交互通讯的时候,遵守的一种规范、规则。

Http协议

针对网络上的客户端 与 服务器端在执行http请求的时候,遵守的一种规范。 其实就是规定了客户端在访问服务器端的时候,要带上哪些东西, 服务器端返回数据的时候,也要带上什么东西。

传输过程

  1. 浏览器建立和服务器的链接
  2. 浏览器将请求数据打包发送请求
  3. 服务器将处理结果打包发送
  4. n次请求响应之后关闭连接

Http相应数据

请求的数据包里面包含三个部分内容 :请求行、请求头、请求体

  • 请求行
  • 请求头
  • 请求体

Http数据包

响应的数据包里面同样包含三个部分内容 :响应行、响应头、响应体

  • 响应行

    • 协议版本

    • 状态码

      咱们这次交互到底是什么样的结果

      • 200 :请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;
      • 403 :for bidden 拒绝访问
      • 404 :请求的资源没有找到,说明客户端错误的请求了不存在的资源;
      • 302:重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location,它指定了新请求的URL地址;
      • 500:请求资源找到了,但服务器内部出现了错误;
      • 304:缓存响应,第一次响应成功之后,会缓存响应页面。
  • 响应头

    • Server: 服务器是哪一种类型。 Tomcat
    • Content-Type : 服务器返回给客户端你的内容类型
    • Content-Length : 返回的数据长度
    • Date : 通讯的日期,响应的时间
  • 响应体
    在这里插入图片描述

Servlet

Servlet体系结构

Servlet接口->GenericServlet抽象类->HttpServlet抽象类->自定义servlet

Servlet的生命周期

  • init()

    服务器进行初始化,只执行一次,默认第一次访问的时候执行

  • service()

    服务器处理业务逻辑,请求来的时候即执行,请求一次执行一次

  • destroy()

    服务器进行销毁,当servlet被移除或服务器正常关闭的时候执行,只执行一次

默认第一次访问的时候,服务器创建servlet,并调用init实现初始化操作,并调用一次service方法,每当请求来的时候,服务器创建一个线程,调用service方法执行自己的业务逻辑,当servlet被移除的时候或服务器正常关闭的时候,服务器调用servlet的destory方法实现销毁操作。

load-on-startup

作用:修改servlet的初始化时机

  1. load-on-startup 元素标记容器是否应该在启动的时候加载这个servlet,(实例化并调用其init()方法)。
  2. 它的值必须是一个整数,表示servlet应该被载入的顺序
  3. 如果该元素不存在或者这个数为负时,则容器会当该Servlet被请求时,再加载。
  4. 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
  5. 正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
  6. 当值相同时,容器就会自己选择顺序来加载

url-pattern的配置

  • 完全匹配

    必须以"/"开始 例如: /hello /a/b/c

  • 目录匹配

    必须"/“开始 以”"结束 例如: /a/ /*

  • 后缀名匹配

    以"*"开始 以字符结尾 例如: *.jsp *.do *.action

优先级:完全匹配>目录匹配>后缀名匹配

ServletConfig对象

作用:

  1. 获取当前servlet的名称
  2. 获取当前servlet的初始化参数
  3. 获取全局管理者
  • String getServletName():获取当前servlet的名称(web.xml配置的servlet-name)
  • String getInitParameter(String key):通过名称获取指定的参数值
  • Enumeration getInitParameterNames() :获取所有的参数名称
  • getServletContext():获取全局管理者

初始化参数是指放在web.xml文件servlet标签下的子标签init-param

ServletConfig对象是由服务器创建的,在创建servlet的同时也创建了它,通过servlet的init(ServletConfig config)将config对象传递给servlet,由servlet的getServletConfig方法获取

ServletContext上下文(全局管理者)

ServletContext是一个项目的引用.代表了当前项目,表述该项目的上下文信息。
ServletContext对象的作用是在整个Web应用的动态资源之间共享数据。我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据。例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了。

服务器会为每个应用创建一个ServletContext对象:当项目启动的时候,服务器为每一个web项目创建一个ServletContext对象,当项目被移除的时候或者服务器关闭的时候,ServletContext销毁。

作用:

  1. 获取全局的初始化参数
  2. 共享资源(xxxAttribute)
  3. 获取文件资源
  4. 其他操作

获取ServletContext

  1. getServletConfig().getServletContext()
  2. getServletContext()

常用方法:

  • String getInitParameter(String key):通过名称获取指定的参数值

  • Enumeration getInitParameterNames() :获取所有的参数名称

    在根标签下有一个 context-param子标签 用来存放初始化参数

    <context-param>
    	<param-name>encoding</param-name>
    	<param-value>utf-8</param-value>
    </context-param>
    
  • void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性。如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同。在一个Servlet中设置数据后,其他Servlet都可以获取该数据。

  • Object getAttribute(String name):用来获取ServletContext中的数据,当前在获取之前需要先去存储才行。

  • void removeAttribute(String name):用来移除ServletContext中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做。

  • Enumeration getAttributeNames():获取所有域属性的名称,获取到的对象是一个枚举集合,该集合能够进行遍历。

  • String getRealPath(String path):获取文件部署到tomcat上的真实路径(带tomcat路径)

  • String getMimeType(String 文件名称):获取文件的MIME类型。

    MIME是邮件和HTTP协议中用来标注网络数据的。常见形式是一个主类型加一个子类型,用斜线分隔。比如text/html、application/javascript、image/png等。

    在访问网页时,MIME type帮助浏览器识别一个HTTP请求返回的是什么内容的数据,应该如何打开、如何显示

路径的写法

  • 相对路径

    当前路径 ./ 或者 什么都不写,上一级路径 …/

  • 绝对路径

    带主机和协议的绝对路径(访问站外资源):http://域名/xxxx,http://localhost:80/day01/hello

    不带主机和协议的绝对路径:/day01/hello

  • 内部路径

    不带协议和主机的绝对路径去掉项目名

JSP(Java Server Page)

  本质上jsp就是一个servlet,在页面嵌套java代码,运行在服务器端,能处理请求,生成动态的内容.
  对应的java和class文件在tomcat目录下的work目录
  后缀名 *.jsp

作用:将内容的生成和信息的展示相分离,servlet写内容的生成,jsp展示信息到页面

JSP基础语法

  1. JSP头文件

    <%@ page language=“java” contentType=“text/html; charset=UTF-8” pageEncoding=“UTF-8”%>

  2. JSP脚本

    • <%!..%>:定义成员变量
    • <%=…%>:向页面输出内容(固定值,变量)
    • <%…%>:书写java代码片段
  3. 注释

    • html注释

      注释的内容只在页面上看不到 java代码和html源代码都有

    • java注释

      只在java源代码中存在

    • jsp注释 <%-- --%>

      只在jsp页面中存在,翻译成java文件之后就没有了

  4. 转发和重定向

    JSP本质上就是一个Servlet,Servlet之间能够进行转发与重定向,那么,Servlet也同样能够转发、重定向到JSP页面上去。

JSP中out.write()和out.print()的区别

1)print方法是子类JspWriter,write是Writer类中定义的方法;

2)重载的print方法可将各种类型的数据转换成字符串的形式输出,而重载的write方法只能输出字符、字符数组和字符串等与字符相关的数据;

3)JspWriter类型的out对象使用print方法和write方法都可以输出字符串,但是,如果字符串对象的值为null时,print方法将输出内容为“null”的字符串,而write方法则是抛出NullPointerException异常。例如:

JSP实现原理

JSP的本质就是Servlet,它只是一种特殊的Servlet。
执行流程:
1.浏览器发送请求,访问jsp页面
2.服务器接受请求,JspSerlvet会帮我们查找对应的jsp文件
3.服务器将jsp页面翻译成java文件.
4.jvm会将java编译成.class文件
5.服务器运行class文件,生成动态的内容.
6.服务器组成响应信息,发送给浏览器
7.浏览器接受数据,解析展示

JSP的指令

  • ▲contentType:设置响应流的编码,及浏览器用什么编码打开,设置文件的mimeType类型
  • ▲pageEncoding:设置页面编码格式
  • ▲import:在jsp中导入包
  • language:jsp支持的语言类型
  • extends:jsp编译成servlet继承的类,默认继承的是HttpJspBase
  • session:在jsp中是否可以直接使用session对象,默认值是true
  • buffer:设置jsp页面流的缓冲区大小,默认值是8kb
  • autoFlush:如果内容超出缓冲区是否会正确输出,默认值是true
  • errorPage:如果jsp页面出现异常,设置跳转到错误页面
  • isErrorPage:当前jsp页面是否是一个错误页面
  • web.xml中配置错误页面
  • isELIgnored:是否忽略el表达式,默认不忽略false
  • include静态包含:<%@include file=“要包含的页面路径”%>
  • taglib: <%@taglib prefix=“前缀名” uri=“名称空间” %>

JSP九大内置对象

在JSP中无需创建就能使用的Java对象就是JSP内置对象,共包含九个内置对象。

域对象

  • application:即ServletContext类的对象,整个项目

  • session:HttpSession类的对象,一次会话

  • request:即HttpServletRequest类的对象,一次请求

  • pageContext:页面上下文对象,一个页面

    主要功能:

    • 域对象功能
    • 获取其他内置对象
    • 代理其它域对象功能

    一个pageContext对象等于所有内置对象,即1个当9个。这是因为可以使用pageContext对象可以获取其它8个内置对象。

普通对象

  • page:this,当前对象
  • out:等同与response.getWriter(),用来向客户端发送文本数据。
  • response:即HttpServletResponse类的对象
  • config:对应“真身”中的ServletConfig
  • exception:只有在错误页面(设置isErrorPage属性)中可以使用这个对象

JSP的动作标签

  • <jsp:forward>:请求转发

  • <jsp:include>:动态包含

EL(Expression Language)

作用:用来替代<%=...%>

  • 减少JSP中 Java 代码。
  • 方便JSP中代码的修改,降低维护成本。
  • 方便非Java工作者(美工修改外观)对页面的修改。

格式:${el表达式}

注意:

1.在EL表达式中,习惯使用单引号’’来表示一个字符串,虽然使用双引号””也是没有问题的。如果输出的内容为一个表达式,我们可以直接编写表达式。

2.如果希望整个JSP忽略EL表达式,需要在page指令中指定isELIgnored=”true”。

3.EL不显示null,当EL表达式的值为null对象时,会在页面上显示空白,即什么都不显示。

EL数据访问

  • 获取POJO对象数据

    ${user.属性名}

  • 获取List数据

    ${userList[0].属性名}

  • 获取Map数据

    ${map[key值]}

Cookie和Session

会话跟踪技术概述

什么是会话?
可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能包含多次请求和响应,例如你给10086打电话,你就是客服端,而10086服务人员就是服务器了。从双方接通电话那一刻起,会话就开始了,到某一方挂断电话表示会话结束。在通话过程中,你会向10086发出多个请求,那么这多个请求都在你一个会话中。
在JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。
在一个会话的多个请求中共享数据,这就是会话跟踪技术,例如在一个会话中的请求如下:
请求银行主页
请求登录(请求参数是用户名和密码)
请求转账(请求参数与转出相关的数据)
请求信用卡还款(请求参数与还款相关的数据)
在这上会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

Cookie与Session
我们知道HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪!
在JavaWeb中,使用session来完成会话跟踪,session底层依赖Cookie技术。

Cookie

Cookie是1993年由网景公司(Netscape)前雇员发明的一种进行网络会话状态跟踪的技术。

​ Cookie翻译成中文是小甜点,小饼干的意思。在HTTP中它表示服务器发送给客户端浏览器的小甜点。Cookie本质上就是一个Map结构的键值对,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。
​ Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了。

Cookie的规范

1、Cookie大小上限为4KB。
2、一个服务器最多在客户端浏览器上保存20个Cookie。
3、一个浏览器最多保存300个Cookie。
在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己更加强大的能力,可能会对Cookie规范进行一些扩展,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!但即便这样也不会出现把你硬盘占满!
注意:不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。

注意:cookie不能跨浏览器

Cookie是通过Http请求和响应头在客户端和服务器端传递的

Cookie的覆盖

如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。

Cookie的方法

  • 新建cookie

    Cookie cookie = new Cookie("name", "wrx");
    
  • 写回浏览器

    response.addCookie(cookie);
    
  • 获取Cookie

    Cookie[] cookies = request.getCookies();
    
  • 获取Cookie的key(即name)和值(value)

    if(cookies!=null&&cookies.length>0){
        for(Cookie c:cookies){
            PrintWriter writer = response.getWriter();
            writer.write("cookie是:"+c.getName()+","+c.getValue()+",");
        }
    }
    

Cookie的生命时长

Cookie对象不只是有name和value,Cookie还是生命时长属性。
所谓生命时长就是指Cookie在客户端的有效时间,可以通过setMaxAge(int)来设置Cookie的有效时间。

设置cookie的有效期,这个值为一个整形值,单位为秒
值>0,表示将cookie存放到客户端的硬盘
值<0,与不设置效果相同,会将Cookie放到浏览器缓存
值=0,表示cookie一生成即马上失效

前提必须路径一致

Cookie的path路径

cookie默认绑定为同一资源路径下。但可以通过setPath指定Cookie绑定的路径。

cookie.setPath(request.getContextPath()+"/aaa");
cookie1.setPath(request.getContextPath()+"/bbb");

扩展:Cookie的domain属性可以让网站中二级域共享Cookie。

以百度网站为例,我们知道百度搜索引擎的地址为:http://www.baidu.com/ 。但百度贴吧、百度学术、百度视频等网站的地址却不是如此,他们如下:
http://zhidao.baidu.com
http://news.baidu.com
http://tieba.baidu.com

不同的域名,实际上代表了不同的应用节点,如何让不同应用节点共享相同的Cookie呢?这就需要使用Cookie的domain属性。
想完成这样操作实际也是比较简单,只需要完成如下的两步:
设置Cookie的path为“/”:c.setPath(“/”)。
设置Cookie的domain为“.baidu.com”:c.setDomain(“.baidu.com”)。
当domain为“.baidu.com”时,无论前缀是什么,只要后缀为“.baidu.com”,都会共享Cookie。

Cookie中保存中文

  注意:cookie不能跨浏览器
            cookie中不支持中文要想支持中文必须编码

Cookie的name和value默认是不能使用中文,如果希望在Cookie中使用中文,name需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。

案例
@WebServlet(name = “DServlet”,urlPatterns = “/dservlet”)
public class DServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(“text/html;charset=utf-8”);
String name = URLEncoder.encode(“姓名”, “utf-8”);
String value = URLEncoder.encode(“张三”,“utf-8”);
Cookie cookie = new Cookie(name,value);
response.addCookie(cookie);
response.getWriter().write(“name:”+name+“
value:”+value);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}

@WebServlet(name = “EServlet”,urlPatterns = “/eservlet”)
public class EServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(“text/html;charset=utf-8”);
Cookie[] cookies = request.getCookies();
for(Cookie c:cookies){
String name = URLDecoder.decode(c.getName(), “utf-8”);
String value = URLDecoder.decode(c.getValue(),“utf-8”);
response.getWriter().write(name+","+value);
}
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}

JSP页面中Cookie的使用

在JSP页面中,我们同样可以使用Cookie,一种方式就是通过哦<%%>标签编写相关的Cookie的代码,另一种就是使用EL表达式内置的Cookie对象。

相比于第一种编写java代码的方式,EL表达式的使用相对简单一些,但是EL只能获取Cookie信息,不能设置Cookie信息。

  如果想设置Cookie信息,只能使用java代码片的方式
  <%
  			response.addCookie(new Cookie("name","zs"));
  			response.addCookie(new Cookie("age","18"));
  %>			

通过EL表达式怎么获取Cookie的值
cookie.name.name:{cookie.name.name}:{cookie.name.value}

cookie.age.name:{cookie.age.name}:{cookie.age.value}

案例:

<% response.addCookie(new Cookie("name","zs")); %> ${cookie.name.name}:${cookie.name.value}
${cookie.age.name}:${cookie.age.value}

Session

Session:服务器端会话技术,是指javax.servlet.http.HttpSession接口,表示一次会话,我们可以把一次会话内需要共享的数据保存到HttpSession对象中。

Session对象的获取

1、HttpSession request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么应用创建session并返回。
2、HttpSession request.getSession(boolean):当参数为true时,与requeset.getSession()相同。当参数为false时,如果当前会话中存在session则返回,不存在返回null。

对于request的getSession()的用法:
一般情况下,若要向Session中写入数据,则需使用getSession(true),即getSession()方法。意义是,有老的用老的,没老的建新的。若要从Session中读取数据,则需要使用getSession(false)。意义是,有老的用老的,没老的返回null。因为要读取数据,只有老的Session中才有可能存在你要查找的数据。新建的Session中是不可能有这些数据的。

HttpSession

1、HttpServletRequest:一个请求创建一个request对象,所以在同一个请求中可以共享request,例如一个请求从AServlet转发到BServlet,那么AServlet和BServlet可以共享request域中的数据.
2、ServletContext:一个应用只创建一个ServletContext对象,所以在ServletContext中的数据可以在整个应用中共享,只要不重新启动服务器,那么ServletContext中的数据就可以共享。
3、PageContext:在一个JSP中的域对象,代表当前JSP页面的范围。
4、HttpSession:一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享session中的数据(即多个无关的Request对象也可以进行数据共享)。

域方法

  • void setAttribute(String name, Object value)
  • Object getAttribute(String name)
  • void removeAttribute(String name)
  • Enumeration getAttributeNames()

▲Session的工作原理

当首次使用session时,服务器端要创建session,session是保存在服务器端,而给客户端的session的id(一个cookie中保存了sessionId)。客户端带走的是sessionId,而数据是保存在session中。当客户端再次访问服务器时,在请求中会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session。

Session的失效时间

默认为30分钟

可通过如下操作自行配置:

30

▲Session的生命周期

session的生命周期
创建:第一次调用request.getsession()创建
销毁:
服务器非正常关闭(断电)
session超时
默认时间超时:30分钟 web.xml有配置
手动设置超时:setMaxInactiveInterval(int 秒) 了解
手动干掉session
★session.invalidate()
存放的私有的数据.

Session中其他常用API

  1. String getId():获取sessionId。
  2. int getMaxInactiveInterval():获取session的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session。
  3. void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除。
  4. long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值。
  5. long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值。
  6. void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId。
  7. boolean isNew():查看session是否为状态新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

监听器和过滤器

监听器

Listener:JavaWeb中的三大组件之一,称之为监听器,用于事件的监听以及事件触发之后的操作。

监听器使用规则:

  1. 他是一个接口,内容由我们来实现。

  2. 它需要注册,例如注册在按钮上。

  3. 监听器中的方法,会在特殊事件发生时被调用。

作用:监听web中的域对象 ServletContext ServletRequest HttpSession

监听内容:

  1. 监听三个对象的创建和销毁

    ServletContextListener
    ServletRequestListener
    HttpSessionListener
    
  2. 监听三个对象属性的变化

    ServletContextAttributeListener
    ServletRequestAttributeListener
    HttpSessionAttributeListener
    

编写步骤

  1. 写一个监听器类:要求必须去实现某个监听器接口

  2. 重写里面的方法

  3. 注册,是在web.xml中配置来完成注册(通过@WebListener注解也可)

    注意:上述三个监听器都是接口,我们可以实现其相应的方法,在发生相应的事件时,完成相关方法的调用。

实现方法

  • ServletContext的监听

    生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用。即Tomcat启动应用时,我们调用contextInitialized方法,Tomcat关闭应用之前,我们调用contextDestroyed方法。

    void contextInitialized(ServletContextEvent sce):创建SErvletcontext时。
    void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时。
    

    属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    void attributeAdded(ServletContextAttributeEvent event):添加属性时。
    void attributeReplaced(ServletContextAttributeEvent event):替换属性时。
    void attributeRemoved(ServletContextAttributeEvent event):移除属性时。
    
  • HttpSession的监听

    生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用。

    void sessionCreated(HttpSessionEvent se):创建session时
    void sessionDestroyed(HttpSessionEvent se):销毁session时
    

    属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    void attributeAdded(HttpSessionBindingEvent event):添加属性时;
    void attributeReplaced(HttpSessionBindingEvent event):替换属性时
    void attributeRemoved(HttpSessionBindingEvent event):移除属性时
    

    JavaWeb监听器还有两个与HttpSession相关的特殊的监听器,这两个监听器的特点如下:

    1. 不用在web.xml文件中进行注册。
    2. 这两个监听器让某个JavaBean类实现监听器接口,然后再把Bean对象添加到session域中,添加该Bean或者销毁该Bean时,触发监听事件。

    这两个特殊的HttpSession监听器如下:
    HttpSessionBindingListener。
    HttpSessionActivationListener。

  • ServletRequest的监听

    生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用。
    void requestInitialized(ServletRequestEvent sre):创建request时
    void requestDestroyed(ServletRequestEvent sre):销毁request时

    属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
    void attributeAdded(ServletRequestAttributeEvent srae):添加属性时
    void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时
    void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

过滤器

过滤器Filter是JavaWeb三大组件之一,它与Servlet很相似!不过它是用来拦截请求的,而不是处理请求的。
当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

编写步骤

  1. 编写一个类
    • 实现filter接口
    • 重写方法
  2. 编写配置文件
    • 注册filter
    • 绑定路径

过滤器的生命周期

  • init(FilterConfig config)

    在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次。

  • doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

    这个方法会在用户每次访问“目标资源(/index.jsp)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行。

  • destory()

    服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法

FilterConfig

  • ServletContext getServletContext():获取ServletContext的方法。
  • String getFilterName():获取Filter的配置名称,与元素对应。
  • String getInitParameter(String name):获取Filter的初始化配置,与元素对应;
  • Enumeration getInitParameterNames():获取所有初始化参数的名称。

多个过滤器的执行顺序

web.xml注册方式:根据web.xml中的注册顺序

四种拦截方式

  • ▲REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
  • ▲FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;
  • INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;
  • ERROR:当目标资源在web.xml中配置为中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。
版权声明:本文为qq_37744716原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37744716/article/details/106362436