HTTP协议
- HTTP协议:超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础
- OSI的体系结构:应用层、表示层、会话层、运输层、网络层、数据链路层、物理层
- TCP/IP的体系结构:应用(各种应用层协议,如TELENT、FTP、SMTP的等)层、运输层(TCP或UDP)、网际层IP、网络接口层
- 五层协议的体系结构:应用层、运输层、网络层、数据链路层、物理层
HTTP请求和响应的步骤:
- 1、客户端连接到web服务器
- 一个HTTP客户端,通常是浏览器,与web服务器的http端口建立一个TCP套接字连接
- 2、发送http请求
- 通过TCP套接字,客户端向web服务器发送一个文本的请求报文。一个报文由请求行、请求头、空行和请求数据4部分组成。
- 3、服务器接受请求并返回http响应
- web服务器解析请求,定位请求资源。服务器将资源复写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成
- 4、释放TcP连接
- 在HTTP/1.0中默认使用短连接,也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其它类型的web资源(如js文件,图像文件,css文件等),每遇到这样一个web资源,浏览器就会重新建立一个HTTP会话
- 而从HTTP/1.1起,默认使用长连接,用于保持连接特性,使用长连接的HTTP协议,会在响应头中添加这行代码:
在使用长连接时,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端在次访问这个服务器时,会继续使用这一条已经建立的连接。但它不会永久保持连接,存在一个保持时间,可以在不同的服务器软件中设置这个时间,实现长连接需要客户端和浏览器都支持长连接connection:keep-alive
- 5、客户端浏览器解析HTML内容
- 客户端浏览器首先解析状态行,查看表明请求是否是成功的状态码,,然后解析每一个请求头,响应头告知以下若干字节为HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口显示
- *** HTTP是一种不保存状态即无状态的一种协议,且不对请求和响应之间的通信状态进行保存。即HTTP协议自身不具备保存之前发过的请求或相应的功能 ***
深入理解面向接口编程
在类中调用接口的方法,而不必关心其具体的实现。这将有利与代码的解耦,使程序有更好的移植性和可扩展性。
请求的转发和重定向
- 请求的转发:/ 代表的是当前的web应用到的根目录
- 请求的重定向:/ 代表的是当前web站点的根目录,即整个http地址
Javaweb中的会话与状态管理
- http是一种无状态的的协,web服务器本身不能识别哪一些请求是同一个浏览器发出的,浏览器的每一次请求都是独立的。
- 作为一个web服务器必须采用一种机制来唯一的标识一个用户,同时记录该用户的状态
HTTP请求方法
http/1.1共定义了八种方法
- 1、GET:向指定资源发出显示请求,使用GET方法应该只用于读取数据,而不应当被作用域产生“副作用
”的操作中,如Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问 - 2、POST:提交资源资源使用
- 3、PUT:更新资源使用
- 4、DELETE:删除资源使用
- 5、HEAD:与GET一样,都是向服务器发出指定资源的请求,只不过服务器不传回资源的文本部分。好处在于使用这个方法可以在
不必传输全部内容的情况下就可以获取其中“关于该资源的信息”(元信息或称元数据) - 6、TRACE:回显服务器收到的请求,主要用于测试或诊断
- 7、OPTIONS:这个方法可使服务器穿你会该资源所支持的所有HTTP请求方法。用 * 来代替资源名称,向服务器发送OPTIONS请求
可以测试服务器功能是否正常运作 - 8、CONNECT
Web服务器
- web服务器是运行及发布web应用的容器,只有将开发的web项目放置到该容器中,才能使所有的用户通过浏览器
访问。开发Java Web应用所采用的的服务器主要是JSP/Servlet兼容的Web服务器。
Web服务器的分类
- Tomcat服务器
- Resin服务器
- JBoss服务器
- WebSphere服务器
- WebLogic服务器
tomcat的目录
-
1、bin:该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat9.exe、
tomcat9w.exe,前者是在控制台下启动Tomcat,后者是弹出GUI窗口启动Tomcat;如果是解压版,那么会有
startup.bat和shutdownn.bat文件,startup.bat启动tomcat,需要JDK的配置 -
2、conf:
- server.xml:配置整个服务器的信息,如修改端口号,添加虚拟主机等
- tomcat-users.xml:存储tomcat用户的文件,保存tomcat的用户名与密码,以及用户的角色信息,可以在其中添加
tomcat用户,之后就可以在tomcat主页中进入tomcat manager页面 - web.xml:部署描述符文件,这个文件中注册了很多MIME类型,即文档类型,这些MIME类型是客户端与服务器之间说明
文档的类型,如用户请求一个html页面,,那么服务器还会告诉浏览器响应文档是text/html类型,这就是一个MIME类型 - context.xml:对所有应用的统一配置,通常我们不会去配置它
-
3、lib:tomcat的类库,里面有很多jar文件,如果需要添加tomcat依赖的jar文件,可以把它放到该文件中,只建议将
tomcat需要的jar文件放到这个目录下 -
4、logs:tomcat的日志文件,记录了tomcat启动和关闭的信息,如果启动报错或异常也会记录在日志文件中
-
5、temp:存放tomcat的临时文件,这个目录下的东西可以在停止tomcat后删除
-
6、webapps:存放web项目的目录,其中每个文件夹都是一个项目;如果这个目录下存在一个目录,那么都是tomcat自带的项目。其中ROOT是一个特殊的项目,在地址栏中没有给出项目目录时,对应的就是ROOT项目
-
7、work:运行时生成的文件,最终运行的文件都在这里。是通过
webapps中的项目生成的!可以删除这个目录下的文件,再次运行时会再次生成。当客户端访问一个jsp文件时,tomcat会通过jsp生成java文件,再编译成.class文件,这个文件就会被放在这个目录下 -
8、LICENSE:许可证
-
9、NOTICE:说明文件
通过url访问服务器:http://服务器IP地址:端口号/项目名/被访问的页面
注:(1)启动tomcat后,tomcat会加载部署在服务器上的所有项目
(2)浏览器访问的页面是服务端的页面,基本上服务器的项目和工作空间的项目要保持一致
tomcat常用操作
- tomcat修改端口号:修改server.xml文件
- tomcat如何管理项目:给Tomcat增加管理员信息,配置conf下的
tomcat-users.xml文件
<tomcat-users>
<role rolename="manager-gui" />
<user username="tomcat" password="tomcat" roles="manager-gui" />
</tomcat-users>
Servlet
- servlet是用java编写的服务器端程序,其主要功能在于交互式的浏览和修改数据,生成动态web内容,servlet是指任何实现了Servlet接口的类
- Servlet运行于支持Java的应用服务器中,从实现上讲,Servlet可以相应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器
- Servlet工作模式:
- 客户端发送请求至服务器
- 服务器启动并调用servlet,servlet根据客户端请求生成响应内容并将其传给服务器
- 服务器将响应返回客户端
Servlet API
- javax.servlet.Servlet接口,及其抽象方法
- init()
- service()
- destory()
- getServletConfig()
- getServletInfo()
- javax.servlet.GenericServlet抽象类,实现了Servlet接口,除了拥有servlet的方法,还有额外的方法
- getInitParameter()
- getServletName()
- getServletContext()
- javax.servlet.http.HttpServlet抽象类,继承了GenericServlet
重载了service方法,额外方法- doGet()
- doPost()
Servlet工作原理
- 1、Servlet接口定义了Servlet与servlet容器之间契约。这个契约是:servlet容器将Servlet类载入内存,并产生Servlet实例和调用它的具体方法。需要注意的是在一个应用程序中,每种Servlet只能有一个实例
- 2、用户请求致使servlet容器调用Servlet的service()方法,并传入一个ServletRequest对象和一个ServletResponse对象。两个对象都是由servlet容器(如tomcat)封装好的,封装过程并不需要程序员去实现,可以直接使用
- 3、ServletRequest中封装了当前Http请求,因此,开发人员不必解析和操作原始的http数据。ServletResponse表示当前用户的Http响应,只需要操作ServletResponse对象就能把响应轻松发给用户
- 4、对于每一个应用程序,servlet容器还会创建一个ServletContext对象。这个对象封装了应用程序上下文的环境详情。每个应用程序值有一个ServletContext对象。每个Servlet对象都会封装Servlet配置的ServletConfig对象
Servlet生命周期
1、当客户端发送第一次请求后,由web容器去解析请求,根据请求找到对应的Servlet,判断该类的对象是否存在,不存在则创建Servlet实例,调取init()方法进行初始化,之后调用service()方法,有service方法判断客户端的请求方式,调用doGet()方法或doPost()方法,处理方法完成后返回相应结果给客户端,单次请求处理结束。
2、当用户发送第二次以及之后的请求,会判断Servlet对象是否存在,但不会再执行init()方法,而是直接执行service()方法,调用doGet或doPost方法
3、当服务器关闭时调用destory方法进行servlet对象的销毁
get和post的区别
-
1、参数传递形式
GET请求时,数据会附加在URL之后,以?分隔URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是Unicode,即是说所有的非ASCII字符都要编码之后再传输
POST请求时会把请求数据放在http请求包的包体中,简单来说GET请求会将数据暴露在地址栏中,而post请求不会 -
2、传输数据的大小
Http规范中没有对url和传输数据的大小进行限制。但在实际开发中,对于GET请求特定的浏览器和服务器对url的长度有限制。
对于POST,由于不是通过url传递数据,理论上数据传输大小不受限制,但实际上不同的服务器会对POST提交数据的大小做出限制,如Apache、IIS都有各自的配置 -
3、安全性
post安全性比GET高,使用get请求,数据会暴露在url中,此外GET请求提交的数据还会受到Cross-site request frogery攻击。
重定向和请求转发的区别
- 1、重定向地址蓝灰改变,request中存储的数据会丢失,转发时地址栏显示是请求页面的地址,request中的数据可以保存下来
- 2、转发属于一次请求一次响应;重定向属于两次请求(地址栏改变两次)两次响应
- 注意:使用js跳转页面,也会使request中的数据丢失
会话
request请求的值只能在单次请求中保存,保存的数据不能跨请求,当重定向时,request中存储的值会丢失
session的数据可以在对个请求中共享,即使是重定向数据也不会丢失;会话中可以包含多个请求
从打开浏览器到关闭浏览器期间访问服务器就称为一次会话
- session常用方法:
方法 | 参数 |
---|---|
void setAttribute(String key, Object obj) | 保存的值以key/value的形式保存在服务器端 |
Object getAttribute(String key) | 通过保存的key取值 |
void invalidate() | 设置session对象失效 |
String getId() | 获取sessionid,第一次登陆成功产生一个唯一的sessionID,如果发现SessionID不同,那么就不是同一次会话 |
void setMaxInactiveInterval(int interval) | 设定session的非活动时间,单位为秒 |
int getMaxInactiveInterval | 获得session的非活动时间,默认是30分钟 |
void removeAttribute(String key) | 从session中删除key指定的对象 |
- session失效的方式
- 调用invalidate()方法
- 调用removeAttribute(“key”)
- 关闭浏览器
注解方式实现Servlet
WebServlet注解
- 从Servlet3.0开始,配置Servlet支持注解方式,同时也保留了
web.xml配置的方式 - 该注解常用属性
属性 | 类型 | 是否必须 | 说明 |
---|---|---|---|
asyncSupported | boolean | 否 | 指定servlet是否支持异步操作 |
displayName | String | 否 | 指定Servlet显示名称 |
initParams | webInitParam[] | 否 | 配置初始化参数 |
loadOnStartup | int | 否 | 标记容器是否在启动时就加载这个Servlet,相当于原来的标签 |
name | String | 否 | 指定Servlet名称 |
urlPattern / value | String[] | 否 | 指定Servlet处理的url |
- 使用注解的注意事项
根元素中不能配置属性metadata-complete=“true”,否则无法加载servlet。
metadata-complete属性表示通知Web容器是否寻找注解,默认不写或false,此时容器会寻找注解,为Web应用程序构建有效的元数据;metadata-complete属性为true,会在启动时不扫描注解,所以用注解进行的配置都将无效
JSP
###JSP中嵌入Java代码的几种方式(几个标签)
- 1、程序代码标签:<%%>
- 2、声明标签:<%!%>
- 3、表达式标签:<%=%>
JSP原理
当浏览器访问jsp页面时,服务器发现为.jsp后缀,会根据路径找到对应的.jsp文件,会将xxx.jsp文件翻译成xxx_jsp.java文件,对这个.java文件进行编译产生一个xxx_jsp.class文件,将class文件加载运行。
如何将.jsp文件翻译为.java文件?
它会将.jsp文件中的html代码通过流的形式进行输出,最终翻译成.java文件,本质上jsp就是一个servlet,往回响应就是jsp中的HTML代码以流的方式写回浏览器。所以在jsp中展示出了HTML代码
JSP九大内置对象
- 1、Page对象:表示JSP页面本身
- 2、Request对象:作用域为同一次请求,主要用于接收通过HTTP协议传送到服务器的数据。(请求头信息、系统信息、请求方式、以及请求参数等)
- 3、Response对象:对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。它的作用域为只在JSP页面内有效
- 4、Session对象:是一个服务器自动创建的一个与用户请求相关的对象。服务器为每个用户都创建一个session对象,保存该用户的信息,跟踪用户的操作状态。该对象内部使用Map来保存数据
- 5、Application对象:作用域为整个服务器
- 6、out对象:用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用outout对象输出数据时,可以对数据缓冲区进行操作,即使清除缓冲区中的残余数据,为其它输出让出缓冲空间。输出完毕一定要关闭输出流
- 7、PageContext对象:可以取得任何返回的参数,,通过它的对象可以获取out、request、response、session、application对象,pageContext对象的创建和初始化都是由容器来完成的,在jsp页面中可以直接使用
- 8、Config对象:获取服务器的配置信息。通过pageContext的getServletConfig()方法可以获取一个config对象
- 9、exception对象:显示异常信息,只有在包含isErrorPage="true"的页面中才可以使用
JSP作用域
PageContext、Request、Session、Application
JSP指令
指令名 | 描述 |
---|---|
page | 定义网页依赖属性,如脚本语言、error页面、缓存需求等等 |
include | 包含其他文件 |
taglib | 引入标签库的定义 |
JSP状态码
状态码 | 消息 | 描述 |
---|---|---|
100 | Continue | 只有一部分请求被服务器接收,但只要服务器没有拒绝,客户端就会延续这个请求 |
101 | Switching Protocols | 服务器交换机协议 |
200 | OK | 请求成功 |
201 | Create | 请求时完整的、新的资源被创建 |
202 | Accept | 请求被接受,但为处理完 |
300 | Multiple Choice | 一个超链接表,用户可以选择一个超链接并访问,最大支持5个超链接 |
301 | Moved Permanently | 被请求的页面已经移动到了新的url下 |
302 | Found | 被请求的页面暂时性的移动到了新的url下 |
303 | See Other | 被请求的页面可以在不同的url下找到 |
400 | Bad Request | 服务器无法识别请求 |
403 | Forbidden | 禁止访问所请求的页面,即无权限访问 |
404 | Not Found | 服务器无法找到所请求的页面 |
405 | Method Not Allowed | 请求所指定的方法不被允许 |
500 | Internal Server Error | 请求不完整,服务器遇到了出乎意料的情况 |
501 | Not Implemented | 服务器不提供所需要的功能 |
502 | Bad Gateway | 服务器从上游服务器接受了一个无效的请求 |
503 | Service Unavailable | 服务器暂时重启或关闭 |
504 | Gateway Timeout | 网关超时 |
505 | HTTP Version Not Support | 服务器不支持所指定的HTTP版本 |
Session和Cookie的区别
- Cookie数据保存在客户端,Session数据保存在服务端
- Session是有服务器端维持的一个存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该sessionID来获取服务器端的session存储空间,sessionID会通过Cookie被保存到客户端,用户在提交数据时,同时也会将sessionID提交到服务器来存取保存的数据。如果客户端禁用cookie,那么session也会失效
- Cookies属于Session对象的一种,不同的是Cookies不会占用服务器资源,是存在与客户端内存或文件中的,Session会占用服务器资源。我们一般认为cookie不可靠,cookie被保存在本机上,其信息的完全看可见性且易于编辑,容易引发安全问题。存在安全问题是Session就相对可靠了
会话与会话状态
-
web应用中会话是指一个客户浏览器与服务器之间发生的一系列请求和响应的过程。
-
web应用中的会话状态web服务器和浏览器在会话过程中产生的状态信息,借助会话状态,web服务器能把属于同一会话中的一系列请求和响应关联起来。
-
在servlet规范中,常有以下两种会话跟踪:
- Cookie
- Session
Cookie
- web浏览器端要能识别出来自同一个浏览器的请求,这需要浏览器对其发出的每个请求都进行标识;属于同一个会话的的请求消息都带有相同的标识号,而属于不同会话的请求消息都带有不同的标识号,称为会话ID(SessionID)
- Cookie机制是采用的是客户端保持http状态信息的方案,是浏览器访问web服务器时,有web服务器在在http响应消息头中附带传送检测l浏览器的一个小文本文件
- 一旦web浏览器保存了某个cookie,在下一次web浏览器请求服务器资源时,会在http请求头中将这个cookie回传给
- cookie底层实现原理:web服务器通过在http响应消息头中添加set-cookie响应头字段,浏览器在http请求消息中添加请求头字段。
- 一个cookie只能标识一种信息,它至少含有标识该信息的名称(name)和设置值(value)
- 使用javax.servlet.http.Cookie 来封装cookie信息
- Cookie类的方法
- 构造方法public Cookie(String name,String value);
- getName() 方法
- getValue() 和 setValue()
- setMaxAge() 和 getMaxAge()
- setPath() 和 getPath()
- HttpSerevletResponse接口中定义了一个addCookie()方法,用于在http响应消息中添加set—Cookie响应头字段
- HttpServletResponse接口中定义了getCookies()方法,得到的是一个数组,用于读取请求消息头中的cookie项
- 默认创建的cookie是一个会话级别的cookie,存储在浏览器的内存中,用户推出后被删除,如果想将cookie存储在磁盘上,需要调用maxAge()方法,并给出一个以秒为单位的时间,设置为0是命令浏览器立即删除该Cookie
- 会话cookie和持久cookie
- 使用setMaxAge()来设置cookie的持久时间,以秒为单位
关于cookie的path
- cookie的作用范围:作用于当前目录和当前目录的子目录,不能作用于当前目录的上一级目录
- 改变上述弊端:设置cookie的作用范围:
//把当前cookie的作用范围设为request.getContextPath()(当前web应用的根目录)
cookie.setPath(request.getContextPath());
session
- session是指一类用来在客户端和服务端保持状态的解决方案。有时候session也用来指这种解决方案的存储结构
- session采用在服务器端来保持http状态信息的方案
- session使用sessionID来区分不同客户,session是以cookie或URL重写为基础的。默认使用cookie,系统会创建一个JSESSIONID的cookie
HttpSession的生命周期
- HttpSession的创建与销毁
1、是不是当浏览器访问服务端的任何一个jsp 或 servlet 时,服务器就会立即创建一个HttpSession对象?
1.1、若当前jsp或servlet是客户端访问的当前web应用的第一个资源,且jsp的session属性指定为false,则服务端就不会创建一个HttpSession对象
1.2、若该资源不是浏览器访问的当前web引用的第一个资源,且其它页面已经创建了一个HttpSession对象,则当前页面会返回一个HttpSession对象,而不会创建新的HttpSession对象
1.3、session=“false”:不允许使用session隐含变量,而不是不能使用session
1.4、servlet什么时候创建HttpSession:
若当前servlet是客户端访问的当前web应用的第一个资源,只有当调用了request.getSession(true)或request.getSessionn()时才会创建一个HttpSession对象
- servlet中获取HttpSession对象
- request.getSession(boolean):若参数为false,若没有和当前jsp页面相关联的HttpSession对象,则返回null;参数为true,则一定返回一个HttpSession对象,如果没有一个与当前jsp相关联的HttpSession对象,那么服务器会创建一个新的HttpSession对象返回,若有直接返回关联对象
- HttpSession对象销毁
- 调用HttpSession对象的invalidate()方法,使当前对象失效
- 卸载当前web应用
- 超过当前HttpSession对象的过期时间
- 设置当前HttpSession对象的过期时间,调用setMaxInactiveInterval();单位为秒
- 在web.xml配置文件中设置HttpSession对象的过期时间: 单位为分钟
- 并不是关闭了浏览器就销毁了session
HttpSession的常用方法
- getID():
- isNew():
- getMaxInactiveInterval():获去HttpSession对象最大时效
- getCreationTime():
- getLastAccessedTime():
URL重写
在访问地址后 加:jsessionid=某个HttpSession对象的sessionid,那么就可以在cookie禁用的情况下,也能找到与服务器对应得HttpSession对象
- 使用encodeURL(“URL重写的地址”)
绝对路径和相对路径
- 相对路径产生的问题:在由servlet转发到jsp页面时,此时浏览器地址为该servlet路径,而若jsp页面的超链接是相对与该jsp页面的地址时,则可能会出现路径混乱的问题
- 绝对路径:相对于当前web应用的根路径的路径,即任何路径都必须带上contextPath(web应用上下文)
- 绝对路径的获取:request 或 application 的getContextPath()方法获取。
关于JavaWeb开发中的 ‘/’ 到底代表什么
- “/” 代表当前web应用的根路径
(http://localhost:8080/contextPath/),若 / 需要交由 servlet 容器来处理。- 请求转发时
- web.xml 中映射servlet访问路径时
- 各种定制标签中的 /
- “/” 代表当前web站点的根路径(http://localhost:8080/),若 / 需要交由浏览器来处理时。
- 超链接</>
- 表单中的action
- 请求重定向时
使用Session来避免表单的重复提交
- 表单的重复提交
- 表单的重复提交情况
- 1、在表单提交到一个servlet,而servlet又通过请求转发的方式响应了jsp(html)页面,此时地址栏还是servlet的路径,在响应页面点击刷新。
- 2、在响应页面没有到达时,重复点击提交键
- 3、在响应页面上点击返回,再提交
- 不是重复提交的情况
- 返回后,再刷新原页面,再提交
- 表单的重复提交情况
- 避免表单的重复提交:提交表单前,需要为表单做标记,在servlet中对标记进行验证,若标记和预定义标记一样,则受理请求,如果不一样,则不受理请求,标记采用隐藏域和session结合的形式,步骤:
- 1.原表单中生成一个随机值
- 2.在原表单中,将随机值放入session和表单中的隐藏域中
- 3.提交表单后,在servlet中获取session值和隐藏域的值,比较两者是否相等,相等则受理请求,并移除session的值。
- 4.不相等,则提示重复提交
session实现一次性验证码
EL表达式
EL语法
-
1、EL语法由 $ 开始,跟上花括号{},在花括号中填写表达式
-
2、EL中使用 . 和 [] 运算符来存取数据
-
3、如果域对象的属性名中有特殊字符(如 . 等),则使用 [] 运算符会很方便
-
4、EL存取变量的方法很简单,例如${username},他的意思是出某一范围中名称为username的变量,因为我们并没有指定哪一个范围中的username,所以它的默认值会从page范围找,如果找不到,再依次到request、session、application中找,如果在中途找到username,就直接回传,不再继续找下去,但是如果全部范围内都为找到,那么就会回传null。
-
5、自动搜索顺序:
属性范围 | 在EL中的名称
— | —
Page | PageScope
Request | RequestScope
Session | SessionScope
Application | ApplicationScope -
5、指定取出哪一个范围内的变量
范例 | 说明 |
---|---|
${PageScope.username} | 取出Page范围内的username变量 |
${RequestScope.username} | 取出Request范围内的username变量 |
${SessionScope.username} | 取出session范围内的username变量 |
${ApplicationScope.username} | 取出application范围内的username变量 |
- 6、与范围有关的隐含变量
其中pageScope、requestScope、sessionScope、applicationScope 都是EL的隐含对象,可以很容易猜出他们的意思 - 7、与输入有关的隐含变量
- param:用于获取某一个请求参数
- paramValue:用于获取多个请求参数
- 8、其它隐含对象
- cookie
- header和headerValues:获取请求头
- initParam:可以获取当前web应用的初始化参数
- pageContext:pageContext即为PageContext对象,只要是只读取属性,就能一直读下去
- 获取contextPath
${pageContext.request.contextPath} 或 ${pageContext.session.id} 或
- 9、EL的关系运算符:关系运算符只能放在EL表达式中,如:
//这样写是错误的
${param.password} == ${param.password1}
//正确写法
${${param.password} == ${param.password1}}
- 10、empty 运算符:empty可以作用于一个运算符,若该集合不存在或该集合为空,其结果都返回true
简单标签(自定义标签)
- 自定义标签可以降低jsp开发的复杂度和维护量,利用自定义标签可以软件开发人员和页面设计人员合理分工 ,将具有共用特性的tag库用于不同的项目,体现了软件复用的思想
- 什么是自定义标签?
使用户自定义的一种jsp标记,当一个含有自定义标签的jsp页面被jsp引擎编译为servlet时,tag标签转化成了对一个称为标签处理类的对象的操作。于是当jsp页面被jsp引擎转化为servlet后,实际上tag标签被转化成了对tag类的处理的操作。
- 自定义标签定义:请参考idea项目JavaWeb_day01中的tag
- 通常情况下开发简单标签,只需要继承SimpleTagSupport类就行了
- 若标签存在标签体jsp引擎将把标签体封装成一个JspFragment对象,调用setJspBody()方法将JspFragment对象传递给标签处理器对象,若标签体为空,JSP引擎将不会调用setJspBody()。调用getJspBody()方法得到jsp页面的标签体对象jspFragment,调用jspFragment的invoke(Writer)方法,Writer为标签体内容的字符输出流,指定标签体的输出位置,如果invoke参数为null,将会将标签体的内容输出到页面。
- 来指定标签体的类型,可以有如下三种类型:
- empty:表示没有标签体
- scriptless:标签体可以包含 el表达式和jsp动作元素,但不能包含jsp脚本元素(如:<%=reques.getParamter(“name”)%>)
- tagdependent:标签体将不会被解析,即直接将标签体中的代码原封不动的传给标签解析类。
- 带有父标签的自定义标签:所有子标签相当于父标签的标签体
EL的自定义函数
- 在EL表达式中调用某个Java类的静态方法,但是这个静态方法需要在web项目中配置才能被EL表达式使用。这个Java类必须被public修饰,而且要配置的方法必须是 public 修饰的 static 方法
- EL自定义函数是为了简化jsp页面操作字符串。
JSTL:JSP标准标签库
- 五大类:1、核心标签库,2、I18N格式标签库,3、SQL标签库,
4、XML标签库,5、函数标签库 - 核心标签库
-
1、表达式操作
- 1.1、<c:out> :主要用来显示数据的内容,如<%=request.getParamter(“name”)%>
- <c:out> 的四个属性:
属性名 | 属性值代表的意思 | 值类型
—|---|—
value | 表示要显示出来的值 |Object
default | 如果value的值为空,则显示dafault的值|Object
escapeXml | 是否转换特殊字符,如 < 转换为<
|boolean- 1.2、<c:set> :主要用来将变量存储至JSP范围中或是JavaBean的属性中
-
2、流程控制<c:if>、<c:choose>、<c:when>、<c:otherwise>
*<c:if>:可以储存比较结果 -
3、迭代操作
- <c:forEach>
- <c:forEach>的属性
属性名 属性值代表什么 属性值是否可以是EL表达式 属性值的类型 属性的默认值 var 存放到指定的成员 否 String 无 items 被迭代的集合对象 是 集合或数组 无 varStatus 用来存放现在指到的相关成员的信息 否 String 无 begin 开始的位置 是 int 0 end 结束的位置 是 int 最后一个成员 step 每次迭代的间隔数 是 int 1 - varStatus:可以获取当前迭代元素的索引(index:集合从0开始),第几个(count:从1开始),是否是最后一个(last),是否是第一个(first)。
-
迭代遍历list集合
<% List<Customer> list = new ArrayList<>(); list.add(new Customer("1")); list.add(new Customer("2")); list.add(new Customer("3")); list.add(new Customer("4")); list.add(new Customer("5")); pageContext.setAttribute("list", list); %> <%-- ites表示要迭代的集合对象,var表示将每次遍历的对象,赋值给customer,后面就可以对其进行操作 --%> <c:forEach items="${pageScope.list}" var="customer"> ${customer.id} <br> </c:forEach>
- URL操作
-
Filter(过滤器)
- 1、过滤器的基本功能:是对Servlet容器调用servlet的过程进行拦截,从而在servlet响应处理的前后实现一些特殊的功能
- 2、Servlet API定义了三个接口供开发人员来编写Filter程序,分别是:Filter、FilterChain、FilterConfig
- 3、Filter程序是一个实现了Filter接口的类,它由servlet容器调用和执行
- 4、Filter程序需要在web.xml中进行注册和设置它可以拦截的资源:Filter可以拦截的资源有Jsp、servlet、静态图片文件和静态html文件
- 5、相关API
- Filter接口及其方法:
public void init(FilterConfig filterConfig) throws ServletException
①、该方法类似于servlet的init()方法,在servlet创建时被调用,而且只被调用一次,该方法对Fliter进行初始化,,Filter实例是单例的。
②、FilterConfig类似于ServletConfig,,也可以在web.xml中配置Filter的初始化参数 - Filter接口及其方法:
<filter>
<filter-name>HelloFilter</filter-name>
<filter-class>com.lcl.filter.HelloFilter</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>lvchunlin</param-value>
</init-param>
</filter>
-
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain
-
Filter的逻辑代码需要写在该方法中。每次拦截都会调用该方法
-
FilterChain:多个filter可以构成一个Filter链
- doFilter(ServletRequest servletRequest, ServletResponse servletResponse):把请求传给Filter链的下一个Filter,如果当前Filter是链中的最后一个Filter,将把请求给到目标Servlet(或Jsp)
- 请求的拦截顺序与filter-mapping的配置先后有关
public void destroy()
-
释放当前Filter所占用的资源,在Filter对象被销毁前调用,而且只被调用一次
-
filter-mapping用于设置一个Filter所负责拦截的资源。一个Filter所拦截的资源可以通过两种方式来指定:servlet名称或资源访问请求路径(url)
- 子元素:指定过滤所拦截的servlet名称
- 子元素 :指定过滤器所拦截资源被servlet容器调用的方式,可以是request、include、forward、error之一,默认是request,可以设置多个子元素用来指定Filter对资源的多种调用方式进行拦截
- request:通过get或post直接访问,就会过滤
- forward:如果目标是通过RequestDispatcher的forward方法访问时,那么该过滤器将会被调用。或<jsp:forward page="" /> 或 通过page指令的 errorPage(<%@ page errorPage="" %>) 转发页面
- include : 如果目标资源是通过RequestDispatcher的include()访问时,那么该过滤器将会被调用,或<jsp:include file=""/>
- error:
Filter的典型应用
1、禁用缓存的过滤器
有三个HTTP响应头字段都可以禁用浏览器缓存当前页面,代码如下:
- response.setDateHeader(“Expirse”,-1);
- response.setHeader(“Cache-Control”,“no-cache”)
- response.setHeader(“pragma”,“no-cache”)
2、字符编码过滤器
可以解决统一转码问题,通过将字符编码配置到web.xml
文件中,在过滤器中获取配置的编码,更有利于编码的后期更改
3、权限处理过滤器
- 权限管理:
- 权限查看
- 修改权限
- 对访问进行权限控制
4、限制下载资源
5、加密解密
6、非法内容过滤
7、验证登录
文件的上传与下载
文件上传
一、表单上传文件
- 1.form的请求方式一定是post
- 2.使用file域
- 3.请求的编码方为: enctype=“multipart/form-data”
- 在servlet中获取表单时,必能使用getParameter()获取请求信息,因为请求的编码方式以被改变,此时是以二进制的方式来提交请求信息,此时需要使用getInputStream() 获取数据输入流.
监听器
- 监听对象
- 监听事件
- 触发行为
JavaWeb监听器(Listener)
-
JavaWeb三大主键:Servlet、Filter、Listener
-
监听器相关概念
- 事件源:被监听的对象(request、session、ServletContext)
- 监听器:监听事件源对象,事件源对象的状态变化都会触发监听器
- 注册监听器:将监听器与事件源进行绑定
- 响应行为:监听器监听到事件源对象的状态改变而执行的功能代码
-
JavaWeb有 8个监听器:
-
1、javax.servlet.ServletContextListener
-
2、javax.servlet.ServletContextAttributeListener
-
3、javax.servlet.http.HttpSessionListener
-
4、javax.servlet.http.HttpSessionAttributeListener
-
5、javax.servlet.http.HttpSessionActivationListener
-
6、javax.servlet.http.HttpSessionBindingListener
-
7、javax.servlet.ServletRequestListener
-
8、javax.servlet.ServletRequestAttributeListener
-
-
按照监听对象分为3类
-
1、监听ServletContext事件
-
ServletContextListener
- 作用:监听ServletContext生命周期的(从创建到销毁的过程(ServletContext服务器启动创建,服务器停止销毁))
-
ServletContextAttributeListener
- 作用:监听ServletContext域中属性变化的
-
-
2、监听HttpSession事件
-
HttpSessionListener
- 作用:监听HttpSession生命周期的(session第一次使用的时候创建;session超时后销毁或session手动销毁(sesssion.invalidate()方法))
-
HttpSessionAttributeListener
- 作用:监听HttpSession域中所有对象的属性变化的
-
HttpSessionActivationListener
- 作用:监听某个对象随着HttpSession活化、钝化的过程
-
HttpSessionBindingListener
- 作用:监听session保存(绑定)对象和从session中移除(解绑)
-
-
3、监听ServletRequest事件
- ServletRequestListener
- 作用:监听ServletRequest的生命周期
- ServletRequestAttributeListener
- 作用:监听request域中属性变化
- ServletRequestListener
-
再次理解Cookie和Session
Cookie
- 特点:
- 1、保存少量信息
- 2、保存的信息都是纯文本
- 3、保存的当前网站下的cookie,每次访问这个网站都会携带给服务器
- 4、默认不支持中文
- 使用
- 服务器如何给浏览器发送并保存cookie
//创建Cookie Cookie cookie = new Cookie("username","zhangshan"); //发送给浏览器 response.addCookie(cookie);
- Cookie有效时间
- 默认会话期间有效(浏览器只要不关,cookie就存在于浏览器的进程中)
- setMaxAge(int):设置cookie的有效时间,秒为单位
- 正数:多少秒后销毁
- 负数:cookie就是会话cookie,随浏览器同生共死
- 0:cookie立即失效
*== 修改或删除cookie都是同名cookie覆盖==
Session
- 服务端保存大量当前会话数据的一种技术,数据可以在同一个会话期间共享
会话控制
- 与服务器交互期间,可能需要保存一些数据,服务器就会为每个会话专门创建一个map来保存数据,这个map就叫session
- 每次创建map时会有一个唯一标识,JSESSIONID
- 浏览器每次访问都会带上它所有的cookie(其中包含JSESSIONID)
特别:
- 会话关闭:默认是cookie没了:通过cookie持久化技术继续找到之前的session
- session失效:自动超时失效或手动失效
令牌机制
- 第一次访问页面时生成一个令牌