软件开发体系架构
-
C/S结构:客户端/服务器
优点: 有一部分代码写在客户端,用户体验比较好
缺点:服务器更新,客户端也要随着更新,占用资源大
-
B/S结构:浏览器/服务器
优点:客户端只要有浏览器就可以了,占用资源小,不用更新.
缺点:用户体验不佳.
Web通信机制:基于请求响应的机制。一次请求,一次响应。
应用技术
客户端技术:html、css、js、jquery、bootstrap、easyui…
Tomcat
-
目录结构
bin:可执行的文件
conf:配置文件
lib:jar包
logs:日志文件
temp:临时文件
webapps:项目部署后的class文件
work:jsp页面生成的文件 -
Tomcat安装
- 直接解压,然后找到bin/startup.bat
- 可以安装
- 驱动之后,如果能正常看到黑窗口,表明已经安装成功.为了确保万无一失,最好在浏览器的地址栏输入:
http://localhost:8080
,如果有看到内容就代表成功了. - 如果一闪而过,则是jdk环境变量没有配置
Servlet
一个运行在我们的Web服务器上,用于接收和响应客户端发来的请求,处理业务逻辑的Java程序。
-
Hello Servlet编写
-
编写一个类
- 继承HttpServlet
- 重写doGet或doPost方法
-
编写配置文件web.xml
- 注册Servlet
- 绑定路径
-
通过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中。
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()输出数据,不然可能会出现异常。
转发和重定向的区别:
- 转发的地址栏是不变的,重定向的地址栏发生变化的。
- 转发是一次请求一次响应,重定向是两次请求两次响应。
- 转发的路径不需要加工程名,重定向的路径需要加工程名。
- request域对象存取的值在转发中是有效的,在重定向中是无效的。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)
什么是协议 ?
双方在交互通讯的时候,遵守的一种规范、规则。
Http协议
针对网络上的客户端 与 服务器端在执行http请求的时候,遵守的一种规范。 其实就是规定了客户端在访问服务器端的时候,要带上哪些东西, 服务器端返回数据的时候,也要带上什么东西。
传输过程
- 浏览器建立和服务器的链接
- 浏览器将请求数据打包发送请求
- 服务器将处理结果打包发送
- n次请求响应之后关闭连接
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的初始化时机
- load-on-startup 元素标记容器是否应该在启动的时候加载这个servlet,(实例化并调用其init()方法)。
- 它的值必须是一个整数,表示servlet应该被载入的顺序
- 如果该元素不存在或者这个数为负时,则容器会当该Servlet被请求时,再加载。
- 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
- 正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
- 当值相同时,容器就会自己选择顺序来加载
url-pattern的配置
-
完全匹配
必须以"/"开始 例如: /hello /a/b/c
-
目录匹配
必须"/“开始 以”"结束 例如: /a/ /*
-
后缀名匹配
以"*"开始 以字符结尾 例如: *.jsp *.do *.action
优先级:完全匹配>目录匹配>后缀名匹配
ServletConfig对象
作用:
- 获取当前servlet的名称
- 获取当前servlet的初始化参数
- 获取全局管理者
- 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销毁。
作用:
- 获取全局的初始化参数
- 共享资源(xxxAttribute)
- 获取文件资源
- 其他操作
获取ServletContext
- getServletConfig().getServletContext()
- 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基础语法
-
JSP头文件
<%@ page language=“java” contentType=“text/html; charset=UTF-8” pageEncoding=“UTF-8”%>
-
JSP脚本
- <%!..%>:定义成员变量
- <%=…%>:向页面输出内容(固定值,变量)
- <%…%>:书写java代码片段
-
注释
-
html注释
注释的内容只在页面上看不到 java代码和html源代码都有
-
java注释
只在java源代码中存在
-
jsp注释 <%-- --%>
只在jsp页面中存在,翻译成java文件之后就没有了
-
-
转发和重定向
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的值
c o o k i e . n a m e . n a m e : {cookie.name.name}: cookie.name.name:{cookie.name.value}
c o o k i e . a g e . n a m e : {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
- String getId():获取sessionId。
- int getMaxInactiveInterval():获取session的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session。
- void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除。
- long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值。
- long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值。
- void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId。
- boolean isNew():查看session是否为状态新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
监听器和过滤器
监听器
Listener:JavaWeb中的三大组件之一,称之为监听器,用于事件的监听以及事件触发之后的操作。
监听器使用规则:
-
他是一个接口,内容由我们来实现。
-
它需要注册,例如注册在按钮上。
-
监听器中的方法,会在特殊事件发生时被调用。
作用:监听web中的域对象 ServletContext ServletRequest HttpSession
监听内容:
-
监听三个对象的创建和销毁
ServletContextListener ServletRequestListener HttpSessionListener
-
监听三个对象属性的变化
ServletContextAttributeListener ServletRequestAttributeListener HttpSessionAttributeListener
编写步骤
-
写一个监听器类:要求必须去实现某个监听器接口
-
重写里面的方法
-
注册,是在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相关的特殊的监听器,这两个监听器的特点如下:
- 不用在web.xml文件中进行注册。
- 这两个监听器让某个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。
编写步骤
- 编写一个类
- 实现filter接口
- 重写方法
- 编写配置文件
- 注册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中配置为中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。