servlet技术
1. HTTP协议
http 是一种应用层的通信协议,一般包括了client和server端。clietn端的过程一般由浏览器执行。服务器端是HTTP服务器。http协议定义客户端和服务器端进行交互的方式,最主要的是HTTP请求和响应的报文格式。
HTTP报文分为三个部分,以请求为例:
- 请求行
- 报文头
- 报文体
知道了大概的HTTP协议之后,下面介绍对HTTP报文进行处理的服务端组件---Servlet.
2. servlet
servlet 即 server applet, 所以可以说servlet是运行在服务端的java程序。 servlet是特殊的java类, 其运行在容器中。其特殊在Servlet中没有main方法。所以Servlet只能由其他类调用执行。
servlet一个基本的定义如下:servlet就是一个java类,并提供基于请求和响应模式的web服务。 换句话说,其是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。
Servlet没有main()方法,他们受控于另外的一个JAVA应用,这个JAVA应用称为容器。
2.1 servlet和servlet容器
servlet相当于真正对用户请求进行处理的组件(类),而容器是对容器是对这些资源进行管理的。
其中tomcat就是一种web容器,其他的web容器有.....
容器提供的功能有:
- 通信支持
容器使得Servlet能够轻松的与web服务器对话,而不用考虑通信细节, - 生命周期管理
- 容器控制Servlet的加载,初始化,以及销毁
- 多线程支持
- 容器自动的为它接收到的Servlet请求创建一个线程。
- 声明安全
- 使用容器,可以使用xml的方式对应用进行声明式部署。
- JSP支持
2.2工作流程
下面描述一次web请求的工作流程。
- 用户发送http请求到服务器端
- 服务器端的web容器接收到请求报文,对其进行解析
- 生成HttpServletRequest和HttpServletRequest实例
- 容器根据请求中的URL找到相应的Servlet, 并为这个请求创建或分配一个线程,并把请求和响应对象传递给Servlet线程
- 容器调用Servlet的Service()方法。该方法根据请求的不同类型,调用doGet方法或者doPost方法。
2.3 接口于实现类
servlet的接口,以及实现的类
2.4 servlet的生命周期
下面是整个的servlet的生命周期 P132
- 容器加载类,调Servlet的无参构造器,并调动Servlet的inti()方法,从而初始化Servlet
- Init方法,在Servlet一生中只调用一次,往往为Servlet为客户请求提供服务前调用
- int()方法使得Servlet可以访问ServletConfig和ServletContext
- 请求到来,Servlet执行service方法
- 对Servlet的每个请求都在一个单独的线程中运行,任何特定的Servlet类都只有一个实例。
- 容器调用Servlet中的destroy方法结束Servlet的生命
Get于POST的区别
总体上说区别如下:
- 传输方式
- HTTP header 和HTTP body
- URL 可见和URL 不可见
- 设计目的
- 获取数据 和发送数据
- 安全性
- 高和低。
具体上二者的区别如下:
- POST方法的消息报文拥有报文体,而Get方法的没有。虽然二者都可以传送参数,但是Get的参数被限制到请求行中。
- Get方法获取数据时,参数直接显示在浏览器地址栏中;而POST方法的参数不会显示在地址栏中
- Get设计用于获取数据,POST设计用于推送数据
- Get方法是幂等的,POST方法不是幂等的。
请求和响应
请求
请求对应着HTTP的请求报文,请求报文由三部分组成:请求行,请求头部,请求体。
从请求中可以获得的参数包含了这三部分的信息。
具体的API可以查看官方文档。
响应
大多数时候,使用响应知识为了向客户发送数据,以下两个方法较为常见:
setContentType
getWriter
重定向和委托
请求重定向
即通过response对象发送给浏览器一个新的url地址,让其重新请求。该过程包含了两次请求,两次响应。
该步骤如下:
- 客户像浏览器地址键入一个URL
- 请求到达服务器/容器
- Servlet决定这个请求应当重定向到另一个完全不同的URL
- Servlet在响应上调用sendRedirect(astring)
- Http响应中含有一个状态码"301", 还有一个Location首部,该值是一个URL。
- 浏览器得到响应,发现了“301”状态码,并寻找Location首部
- 浏览器使用该Location中的值重新建立请求,此时浏览器地址栏的URL发生变化
- 用户得到新的请求结果。
sendRedirect(String address)取一个String作为参数,而不是URL对象。
注意:: address是重定向的路径,该路径可以是绝对路径也可以是相对路径,因为重定向可以重定向到其他站点,所以使用绝对路径时,需要写明web站点的全称,例如:"/web_project/send_redict".当使用相对路径,默认的就是重定向到当前的站点的路径下面。此时只用写"send_redict".
请求分派/转发
大致的工作流程如下:
- 用户在浏览器的地址栏键入URL
- 请求到达服务器
- Servlet决定这个请求应该分配给web应用的另一部分
- Servlet调用如下代码:
RequestDispatcher view= request.getRequestDispatcher("result.jsp")
view.forward(request, response);
- 此时Jsp 接管该请求和响应
- 浏览器以正常的方式得到响应,显示给用户,浏览器的地址栏并没有变化,所以用户不知道是由JSP生成的响应
上面中的result.jsp是处理该请求的新对象,其一般的是一个地址,其实转发的路径,其可以是相对路径,也可以是绝对路径,对于绝对路径(该路径在servlet-mapping中配置过,所以有相应的servlet进行处理)。例如上面的代码同样可以写成:
RequestDispatcher view= request.getRequestDispatcher("/forwardExample")
view.forward(request, response);
<servlet-mapping>
<servlet-name>ServletForwardExample</servlet-name>
<url-pattern>forwardExample</url-pattern>
</servlet-mapping>
请求转发对象不仅仅可以通过request对象获得,也可以通过servletContext对象。下面是例子:
rd=this.getServletContext().getNamedDipather("ServletForwardExample") //这里的参数是servlet的名字,需要在web.xml中配置过的
rd=this.getServletContext().getRequestDispatcher("/forwardExample") //这里只能填写绝对路径
注意的是通过ServletContext获取的话参数的设置。
RequestDispatcher 包含两个方法:forward()和include方法。forward()方法较为常见。
区别
- 浏览器地址栏变化
转发时地址不变化,重定向地址变化 - 请求范围
重定向可以重定向到站外资源,转发时不行 - 请求过程
- 转发时一次请求转发,重定向是两次请求,两次响应。
servlet 配置信息
分为两种配置,局部配置 和全局配置
- servletConfig针对具体的Servlet的config
- ServletContext代表该web应用的config
上面的参数针对之前已知的信息,且因为参数只是容器启动或者Servlet初始化调用才进行读取,构造吗,所以servletConfig,ServletContext中的配置信息在运行期间不变,除非重新启动,部署。
如果不同的Servlet之间的共享信息不是事先知道的呢? 属性信息
属性
属性就是一个对象,设置到另外的三个Servlet对象中-ServletContext, HttpServletRequest, HttpSession中去的。
属性Vs参数
属性是可变的,所以就意味着其存在安全你性问题。所以有下面对于servlet的并发运行的安全问题。
读取外部资源配置文件信息,三个方法:
参见: http://blog.csdn.net/mr_li13/article/details/48598361
http://blog.csdn.net/u011702171/article/details/50908407
监听器和过滤器
过滤器
- 过滤请求和响应
- 自定义过滤规则
- 用于对用户请求进行预处理,和对请求响应进行后处理的web应用组件。
常用的场景
- 用户认证
- 编解码处理
- 数据压缩处理
过滤器生命周期
只会创建一次
监听器
- 监听事件发生,在时间发生前做出相应处理的web组件
分类 - 监听应用程序环境Servletcontext
- 监听用户请求对象 ServletRequest
- 监听用户会话对象Httpsession
监听器的应用场景
- 应用统计
- 任务触发
会话管理
使用场景
- 记录用户偏好
- 记录用户登录状态
- 浏览记录
原理
客户端或者服务器端保存用户数据。因为Http协议是无状态的。
两种会话管理方式
- cookie: 会话数据保存在客户端
- session. 会话数据保存在服务器端
cookie的工作原理
目的:: 因为Http协议是无状态的,所以Cookie被设计用来保存和识别用户。
形式:
- 会话数据
- 保存在客户端
- key-value的形式
下面几篇文章介绍了session和cookie的原理,参考我文献也很重要:
http://blog.csdn.net/guoweimelon/article/details/50886092
http://www.sohu.com/a/100667614_448410
区别:
cookie 和session 的区别:
cookie数据存放在客户的浏览器上,session数据放在服务器上。
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
生命周期上的不同: cookie 是累计时间的,即到点就失效的, session是间隔性的失效的,比如设置20分钟失效,这个时间是从最后一次访问session的时间开始算的。
session也可以直接调用api来使session失效。
web 应用程序结构
- 静态文件
- META-INF 元信息
- WEB-INF
- class
- lib
- web.xml 部署描述符,描述一个web程序
首先是个XML文件 ,
其次是设置web应用程序的组件部署信息
servlet容器需要支持部署描述符的所有元素
DD配置
映射
<load-on_startup>改变servlet默认的初始化时间。
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<welcome-file-list>
</welcome-file-list>
参考:http://blog.csdn.net/guihaijinfen/article/details/8363839
在web.xml文件中同样可以配置<mime-mapping>,其可以对制定的文件制定打开方式。
可以参考:http://jxdwuao.iteye.com/blog/1637809
Servlet并发处理
特点:
- 单实例
- 多线程
- 线程不安全
servlet线程安全
- 变量的线程安全
- 参数变量本地化
- 使用同步块synchronized
- 属性的线程安全
- ServletContext线程不安全
- HttpSession理论上线程安全
- ServletRequest线程安全的
- 避免在Servlet中创建线程
- 多个Servlet访问外部对象加锁
容器启动组件顺序: 监听器,过滤器,servlet
JSP
JSP 中的六种指令
JSP指令
- 脚本代码 <% code %>
- 指令 <%@ Instruction %>
- 表达式 <%= %>
- 声明 <%! %>
- 注释 <%% -- z注释 -->
6种指令在生成代码的不同。与注意事项。
下图显示了容器如何处理JSP:
JSP声明
- 一个声明语句可以声明一个或多个变量,方法,供后面的JAVA代码使用
- <% !%>
- 表达式元素中可以包含任何符合JAVA语言规范的表达式
- <% = % >
jsp 脚本
- 脚本程序可以包含任意的JAVA程序
JSP注释
<% -- 注释内容--%>
JSP指令
主要设置JSP页面的属性
- page指令
- 定义页面的依赖属性,比如脚本语言,error页面,缓存需求等
- include指令
- 包含其他文件 - taglib指令
JSP内置对象
可以直接使用而不用申请