在前面的学习中知道HTTP是一套网络通讯协议,并且它是一种无状态的协议。这里无状态的html
含义是指客户端web浏览器和web服务器之间不须要创建持久的链接,这意味着当一个客户端向java
服务器发出请求(HttpRequest),而后web服务器返回响应(HttpResponse)以后链接就关闭了,web
在web服务器上不保留链接的信息。apache
HTTP协议遵循请求(Request)/应答(Response)模型,浏览器向服务器发送请求,服务器处理浏览器
请求并返回适当的应答。其一次链接被构形成一次请求和应答。服务器
在完整的一次请求、应答模式中HTTP通讯的过程为如下七个步骤:网络
一、创建TCP链接框架
在HTTP协议开始工做以前,浏览器和服务器首先须要创建链接,该链接是经过TCP来完成的jsp
二、浏览器向服务器发送请求指令ide
TCP链接创建了之后,浏览器就能够向服务器发送请求指令了。
常见的位POST和GET
三、浏览器发送请求头消息
浏览器发送请求命令以后,还要以头消息的形式向服务器发送一些别的信息,以后浏览器发送
一行空白行来通知服务器其已经结束了头信息的发送。
四、Web服务器响应
浏览器发送请求后进行一些相关逻辑的处理以后,服务器会向客户端浏览器返回应答。
例如:HTTP/1.1 200 OK 版本号+状态码
五、web服务器发送应答头信息
如同客户端同样,服务器应答也会想用户发送关于他本身的数据和被请求的文档信息。
六、web服务器向浏览器发送数据
向浏览器发送头信息,一样以空白行来表示头信息的发送结束。以后以Content-type应答
头信息所描述的格式发送实际的数据。
七、web服务器关闭TCP链接
当实际的数据发送完毕以后,Web服务器关闭TCP链接。不过服务器或者浏览器头信息
加入了Connection:keep-alive。TCP链接在数据发送完毕以后仍然保持的是打开状态。
缩短了下一次链接创建的时间,节约了网络带宽。
HTTP请求信息由三部分组成:
请求方法URI协议/版本、请求头(Request Header)、正文
HTTP/1.1 表示的是HTTP一些的版本,GET表示请求的方法,/sample.jsp表示资源URI。
在Intenet应用中经常使用的请求方法是GET和POST,固然还有其余的一些方法例如HEAD、PUT
URI完整的指定了要访问的网络资源,通常状况下只须要给出相对于服务器根目录的相对目录
便可。
上述中GET方法和POST方法由很大的区别,笔者会找个时间作一个总结。
以一行空信息为结束标志,请求头信息包含了一些客户端环境信息和一些正文信息。
请求正文包含客户端提交的查询字符串的信息。通常状况下查询字符串信息是经过表单
传递给服务器,进行一些逻辑的处理,例如登陆,注册等功能。
了解了HTTP协议和HTTP请求的相关内容,咱们可能会思考一个问题:Servlet中如何获取
HTTP请求信息来实现相关的业务逻辑呢?
接下来笔者将实际进行一下演示,来讲明Servlet对HTTP请求的处理。
阅读源码能够知道HTTP请求是封装在HttpServletRequest对象中的。
不过这里咱们会发现HttpServletRequest是一个接口,是不能直接实例化的,不过根据Java
的多态性质咱们不难猜测到,具体实例化的确定是实现此接口的子类,不过咱们如何知道是哪
个类呢?(其实这里实例化的是Tomcat容器里面的类)
利用反射嘛,合理的运用反射在一些框架的学习中是十分有必要的。
class org.apache.catalina.connector.RequestFacade这里是笔者经过反射获得的结果,具体的类在Tomcat容器中,对于Tomcat的学习笔者
有时间的时候会进行下去的。
咱们如今知道HttpServletRequest封装了HTTP请求的相关信息,这些信息咱们如何获取呢?
读者能够去查阅其源码。这里笔者给出一些比较经常使用的方法。
getHeader(name):返回指定的请求头的信息。
............
getMethod():获取HTTP请求的方法。
getContextPath();获取请求URI资源的上下文路径
getServletPath();获取Servlet的映射路径
getPrarameter(parameterName)
............................................................
这里Tomcat在实现了对HTTP请求的封装以后,还提供了请求派发的功能:每一个客户的请求
能够传递给多个Servlet、web应用程序中的其余资源。整个的过程是在服务器端完成的,没有
任何客户端的参与不须要在客户端浏览器和服务器之间传递什么特殊的信息。
研究其源码能够发现其是借助于RequestDispatcher对象来实现的。
须要注意的是RequestDispatcher提供了两种派发的方式:
include、forward();二者的区别在于forward()方法只会输出后面页面的内容,而include()
方法两个页面都会输出。
package com.kiritor.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class HelloServlet */ public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public HelloServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getMethod()); System.out.println(request.getContextPath()); System.out.println(request.getHeader("User-Agent")); System.out.println(request.getParameter("username")); } }这里咱们直接看输出结果吧:
至于其余的方法,笔者这里就很少讲了,读者本身去看源码,写实例尝试吧。
以后一篇文章将会就HTTP响应,以及Servlet如何处理HTTP的响应作一些总结、学习。
OK,这篇文章就到这儿了!