javaweb中的servlet相关知识
class01 javaweb基础
一.OSI参考模型:
应用层、表示层、会话层
传输层、
网络层、
数据链路层、
物理层一共七层
二.与OSI参考模型对应的TCP/IP四层模型:
应用层、
传输层、
网际层、
网络接口层
三.http协议的主要特点:
- 遵循请求/响应模型
- 无连接:每次连接只处理一个请求 处理完请求后就释放连接
- 无状态:http协议对于事物处理没有记忆能力 即每次连接互不影响
- 灵活:可以传输任意类型数据对象
- 简单快捷:客户端向服务器发送请求时,只需要传送请求和路径
四.http协议——请求:
请求行、请求头、空行、消息体
请求行的内容有 方法 url 版本
五.http协议——响应
状态行、响应头、空行、消息体
状态行的内容有 版本 状态码 描述
六Web容器对servlet的支持包括:
- 通信支持
- servlet生命周期管理
- 多线程支持
- jsp支持
- 处理安全性
七.什么是servlet?
1. 用java语言编写的Java类
2. 在web容器中运行
3. 用于处理客户端请求
八.servlet的生命周期
- 创建程序
- 初始化
- 服务
- 终止
- 卸载
九.web.xml中<url-pattern>的匹配方式:
- 完全匹配
- 目录匹配
- 扩展名匹配
查找规则:按完全匹配、目录匹配、扩展名匹配的优先级匹配
如果一个请求可以匹配多个目录,容器会选择最长的目录匹配
class02 使用servlet处理http响应
1.servletconfig对象为servlet提供初始化参数 注1
2.servletcontext对象属于整个web应用程序 注2
3.响应分为:状态行、响应头、空行、消息体
状态行又由 http版本、状态码、状态描述信息三部分组成
在使用PrintWriter向客户端输出信息之前,设置状态码
设置状态码的方法:response.sendError(args0,args1);
args0是状态码,args1是状态描述
100-199:表示信息性代码,标示客户端应该采取的其他动作,请求正在进行。
200-299:表示客户请求成功。
300-399:表示用于已经移走的资源文件,指示新的地址。
400-499:表示由客户端引发的错误。
500-599:表示由服务器端引发的错误。
常见状态码:200请求成功 302请求重定向 400请求参数有误或无法被服务器理解404未在服务器找到该资源
500服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理
4.getwriter方法与getoutputstream方法的区别
getWriter方法用于字符输出流对象(输出文本数据)
getOutputStream用于字节输出流对象(输出二进制数据)
5.请求的重定向与请求的转发
请求重定向指的是客户端向服务器发出请求,服务器中的servlet响应一个新的url地址给客户端,客户端再根据这个地址向服务器发出请求。
特点是:至少两次请求,至少两次响应,url发生了改变(主要用于不同服务器之间的跳转)
请求转发指的是客户端向服务器发出请求,服务器中的一个servlet将这个请求转发给服务器内部的另一个servlet,最终实现响应
特点:一次请求,一次响应,url没有发生改变。(主要用于同一个服务器内部servlet之间的转换)
使用的方法response.sendredirect(url地址);
6.设置自动刷新和等待页
使用方法response.setHeader("refresh","time;URL:url");
这是部分浏览器厂商的扩展功能,不是标准http协议的内容,因此有兼容性问题
注释1:servletconfig对象
每个servlet都可以通过方法this.getServletConfig()的方式得到自身的servletconfig对象
在Servlet的配置文件(即web.xml)中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。(配置在某个servlet标签下)
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
eg:<servlet>
<servlet-name>InitParamServlet</servlet-name>
<servlet-class>com.lovo.InitParamServlet</servlet-class>
<init-param>
<param-name>parametername</param-name>
<param-value>Servlet初始化参数值</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>InitParamServlet</servlet-name>
<url-pattern>/InitParamServlet.do</url-pattern>
</servlet-mapping>
所以,要得到初始化参数信息,可以使用config.getInitParameter("参数名")的方式获得,其中config为servletconfig类实例化的对象,一般在servlet初始化调用init(ServletConfig config)方法时会有一个config。每个servlet里都有一个servletconfig
servletconfig常用的两个方法有config.getInitParameter("参数名")得到某个初始化参数值;
config.getservletcontext()得到应用上下文对象servletcontext;
注释2:servletcontext对象
eg:
在web容器启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用,相当于web应用的一个全局变量。
因此一个WEB应用中的所有Servlet共享同一个ServletContext对象,Servlet对象之间可以通过ServletContext对象来实现通讯
通讯的方法就是一个servlet对象用自身的servletconfig得到servletcontext对象,servletcontext对象.setattribute("password", "123456")键值对的方式设置;
另一个servlet对象用自身的servletconfig得到servletcontext对象,servletcontext对象.getattribute("password")键的方式获取值“123456”;
对于每一个servlet来说可以由这个servlet的config(servletconfig对象)获得,通过config.getservletcontext()方法获取。
因此servlet-context需要配置在整个web-app下
eg:
<context-param>
<param-name>webInitParm</param-name>
<param-value>Web初始化参数</param-value>
</context-param>
class03使用servlet处理http请求
1.Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象(即HttpServletRequest对象)、和代表响应的response对象 (即HttpServletResponse对象)。
Request 对象用于接收客户端浏览器提交的数据,而 Response 对象的功能则是将服务器端的数据发送到客户端浏览器。
2.浏览器向web服务器发送http请求的三种方式:
- 在浏览器地址栏中输入url地址 只会是http协议的get方法
- 超链接 只会是http协议的get方法
- 提交表单 可以是get方法也,可以是post方法
默认情况下都是http协议的get方法
3.http协议的get方法和post方法的区别:
- 提交数据类型:get只能是文本,post可以是文本也可以是二进制数据(如图片、音乐、电影等)
- 提交数据长度:get方法不超过255字符 ,post方法没有限制
- 提交数据的可见性(即安全性):get可见(因为get是直接在网址上加上?name=“”&password=“”这种方式),post不可见(因为post是作为消息体)
- 提交数据是否会留下缓存:get有缓存,post没有缓存
因为以上特性,所以在发送保密信息,上传文件时需要使用post。请求获取静态页面和下载文件时使用get。
4.request对象由请求头、请求行、空行、消息体组成。请求行又分为请求方法 请求的url地址 http协议版本
- 获取请求行的方法:request.getMethod()/request.getRequestURL()/request.getProtocol() 常用的这三种还有几种不常用的
- 获取请求头的方法:request.getHeader(name)获取名为那么字段的值/request.getHeaders(name)获取所有名为那么字段的值/request.getHeaderNames()获取所有请求头字段名称 从请求头中我们可以通过request.getHeader("user-agent")的方法的到浏览器信息,根据里面是否含有Firefox/Chrome/MSIE来确定浏览器的种类
- 获取请求消息体的方法(如果是post方法 即是表单数据 如果是get 消息体里没有实质内容):
如果是获取文本对象,则使用方法request.getParameter(name);获取消息体(即表单数据)中名为name的参数
如果表单数据中有如复选框这样的数据,那么一个参数就有多个值,需要用到方法getParameterValues(name);
如果要获取二进制对象,则需要用到方法request.getinputstream()和request.getreader()方法,这两个方法都是获取二进制对象,区别在于request.getreader获取了二进制对象后返回的是字符对象,而request.getinputstream()方法最终返回的是字节对象。(即二进制数据)
同理response.getwriter()和response.getoutputstream()都是输出二进制对象,但是最终response.getwriter()输出的是字符对象,而response.getoutputstream最终输出的是字节对象。
5.四个已经学习了的内置对象:
request、response、servletconfig、servletcontext
6.请求的重定向与请求的转发区别:
- 重定向是由客户端浏览器来完成,请求转发是服务器来完成
- 重定向浏览器的url会发生改变,请求转发不发生改变
- 重定向是两次请求、两次响应,请求转发是一次请求一次响应。
请求转发常用于动态网页,将request对象和response对象一起从一个sevlet转到另一个servlet处理请求。
请求重定向则常用于静态网页
请求重定向的代码如下:
使用的方法response.sendredirect(url地址);可能看上去很怪,不是请求重定向么,那不是应该request.sendredirect(url地址)
这是因为重定向发生的时机为 第一次请求—》第一次响应(response.sendredirect(url地址);)—》浏览器客户端—》第二次请求(请求的地址从第一次响应中来)—》第二次响应
请求转发代码如下:
首先得到RequestDispatcher对象(翻译为请求的调度对象) 然后将请求对象和响应对象转发给下一个servlet
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/FormServlet.do");
requestDispatcher.forward(request, response);
7.请求范围
(可以参考全局变量和局部变量来理解,如servletcontext的作用范围是整个web应用 整个web应用只有一个servletcontext对象
而servletconfig得作用范围是自身的servlet内部)
以request对象和response对象为例,每一次客户端请求使服务器产生一个request对象和response对象,而这两者的生命周期止于这一次请求响应结束(就会被销毁)。
下一次请求(由于和上一次请求很可能不同)又会产生新的request对象和response对象。
如果发生了请求转发,那么这一个request对象和response对象就会一直存在,直到最后一个servlet处理完这一对request对象和response对象再销毁。
回顾:
servletcontext的特点: 1.一个web应用只会产生一个servletcontext
2.它相当于一个大仓库,可以存放和取出数据,因此一个web应用中的不同servlet可以通过servletcontext进行通讯
3.servletcontext可以完成虚拟路径和物理路径的转换(这个目前还没学习到好像)
注意:表单数据是放在用post方法发送的请求的消息体里,而不是servletcontext里。
class04web状态管理
1.文件的下载
2.文件的上传
- 上传单个文件
- 上传多个文件
3.web状态管理实现的三种方式:
- 表单隐藏字段 不足:必须是动态页面才生效 不支持静态页面
- 客户端浏览器缓存文件cookie
- session会话解决方案(如果还是禁用cookie则启用url重写)
class05
三大内置对象作用域分析、监听器、过滤器
一、三大内置对象分别为应用上下文对象servletcontext、会话对象httpsession、请求对象http servlet request
1.servletcontext对象作用域
对于整个web应用,只有一个servletcontext对象。web应用中的所有servlet都可以访问它。线程不安全。存活时间最长,消耗资源最多,作用域范围最大。
在servletcontext对象中应尽量少量保存不会被修改的数据,常用的方法是使用单例模式来处理共享数据。
2.session对象作用域
session对象用于维护与一个客户的会话状态。
session对象只存在于用户的会话期间,数据不能被整个web应用访问。理论上线程安全,存活时间中,消耗资源中,作用范围中。
3.servletrequest对象作用域
只用于客户端一次请求过程,每一次请求,都会产生一个新的request对象。线程绝对安全,存活时间短,消耗资源少,作用范围小。
共同点:三大内置对象都可以存取属性,通过get/setattribute()的方法
二、监听器分为八类
三大内置对象都有两类监听器,即生命周期监听器、属性改变监听器。session对象除此之外还多了对象绑定监听器和会话转移监听器(不做要求,这是分布式的内容)。
三、servlet 过滤器
常见应用:
1.认证过滤
2.登录和审核过滤
3.图像转换过滤
4.数据压缩过滤
5.加密过滤
过滤器链:
四、四个包装器类:
servletrequestwrap
sevletresponsewrap
httpservletrequestwrap
httpsevletresponsewrap
class06 装饰者设计模式与jsp基础
一、装饰模式(Decorator pattern):动态地给一个对象添加一些额外的职责。就添加功能来说,装饰模式比类继承实现更为灵活。其别名为包装器(Wrapper)。
装饰模式是一种对象结构模式。
装饰模式的简单范本:
1.有一个功能接口2.有一个被装饰者类实现功能接口,且有一个装饰者基类实现功能接口,装饰者基类包含一个功能接口为成员变量3.不同的具体装饰者类继承于装饰者基类。
装饰者模式的优缺点:
优点:
1.装饰模式与类继承的目的都是要扩展对象的功能,装饰模式可以提供比类继承更多的灵活性
2.通过使用不同的具体的装饰类以及这些装饰类的排列组合,开发者可以创造出很多不同行为的组合
缺点:
1.这种比类继承更加灵活机动的特性,也同时意味着装饰模式比类继承更容易出错
2.使用装饰模式增加了代码的复杂度
装饰模式的使用场景
1.在不影响其他对象情况下,以动态透明的方式给单个对象添加职责,需要动态地给一个对象添加功能,这些功能可以再动态地被撤销
2.当不能采用类继承的方式进行扩展时 一种情况是,可能有大量独立的扩展,每一种组合将产生大量的
子类,使得子类数量呈爆炸性增长,另一种情况可以使因为类定义不能继承(final)或不能用于生成子类。
需要注意的问题:
1.一个装饰者类的接口必须与被装饰者的接口一致
2.尽量保持具体装饰者类作为一个“轻类”,也就是说不要把太多的逻辑和状态放到具体装饰类去实现,逻辑和状态应被放到被装饰者类。
二、jsp基础(java server page)
1.servlet缺陷:
不方便使用html代码
部署繁琐容易出错
不利于项目分工(即区分前后端)
2.jsp本质:
jsp的本质是一个简化的servlet设计
它是在传统的html代码中插入java程序段和jsp标记,从而形成jsp文件,后缀名为.jsp 。这样可以将动态内容与静态内容区分开来。
3.jsp的生命周期
翻译(由jsp引擎将jsp页面翻译成java代码)
编译(将java代码编译成class字节码文件)
类加载(将class字节码文件加载到web容器)
类实例化
初始化
提供服务
销毁
注:在jsp生命周期中,整个编译和翻译步骤只发生一次。
也就是说,JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例——JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。JSP其实也是Servlet的一种简化,使用JSP时,其实还是使用Servlet,因为Web应用中的每个JSP页面都会由 Servlet容器生成对应的Servlet。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。
4.jsp的组成
jsp主要由元素、模板数据(模板数据即html代码)两部分组成。元素又分为脚本元素、指令、动作。脚本元素又分为声明、scriptlet、脚本表达式三部分
脚本元素包括:
1.声明
格式为:<%! 声明内容 %> ,用于在jsp程序中声明合法的变量和方法
2.scriptlet
格式为:<% 代码内容 %>,用于插入java代码片段到模板数据。
3.脚本表达式
格式为:<%= %>,用于直接输出内容 就像out.println();
5.jsp的注解
1.html/xhtml注释:<!-- -->
这种注释和html中的注释很像,唯一不同之处就是可以在这个注释中使用脚本表达式
2.scriptlet注释:// /* */
由于scriptlet包含的是java代码 所以java中的注释规则在scriptlet中也适用
3.隐藏注释:<%-- -->
这种注释写在jsp程序中,但是不发给客户端。