spring源码分析之spring-web http详解
spring-web是spring webmvc的基础,它的功能如下:
1. 封装http协议中client端/server端的request请求和response响应及格式的转换,如json,rss,xml等。
2. 远程调用包括jaxws、caucho、httpinvoker
3. web相关的accept/bind/client/context/filter/jsf/method/multipart
先从http协议中的封装来看:

先了解一下http的基础:(来自:http://blog.csdn.net/lxzo123/article/details/6708035 HTTP协议——请求格式及方法)
一、HTTP请求格式
当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:
① 请求方法 URI 协议/版本
② 请求头(Request Header)
③ 请求正文
下面是一个HTTP请求的例子:
GET/sample.Jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=1234
(1)请求方法URI协议/版本
请求的第一行是“方法URL协议版本”:GET/sample.jsp HTTP/1.1
以上代码中“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本。
根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet应用中,最常用的方法是GET和POST。
URL完整地指定了要访问的网络资源,通常只要给出相对于服务器的根目录的相对目录即可,因此总是以“/”开头,最后,协议版本声明了通信过程中使用HTTP的版本。
(2)请求头(Request Header)
请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
Accept:image/gif.image/jpeg.*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
(3) 请求正文
请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:
username=jinqiao&password=1234
在以上的例子的HTTP请求中,请求的正文只有一行内容。当然,在实际应用中,HTTP请求正文可以包含更多的内容。
四、HTTP请求方法:GET POST
1)GET方法
GET方法是默认的HTTP请求方法,我们日常用GET方法来提交表单数据,然而用GET方法提交的表单数据只经过了简单的编码,同时它将作为URL的一部分向Web服务器发送,因此,如果使用GET方法来提交表单数据就存在着安全隐患上。例如
Http://127.0.0.1/login.jsp?Name=zhangshi&Age=30&Submit=%cc%E+%BD%BB
从上面的URL请求中,很容易就可以辩认出表单提交的内容。(?之后的内容)另外由于GET方法提交的数据是作为URL请求的一部分所以提交的数据量不能太大
2)POST方法
POST方法是GET方法的一个替代方法,它主要是向Web服务器提交表单数据,尤其是大批量的数据。POST方法克服了GET方法的一些缺点。通过POST方法提交表单数据时,数据不是作为URL请求的一部分而是作为标准数据传送给Web服务器,这就克服了GET方法中的信息无法保密和数据量太小的缺点。因此,出于安全的考虑以及对用户隐私的尊重,通常表单提交时采用POST方法。
从编程的角度来讲,如果用户通过GET方法提交数据,则数据存放在QUERY_STRING环境变量中,而POST方法提交的数据则可以从标准输入流中获取。
言归正传:
http基础
1. httpRequest继承自HttpMessage定义了http请求的基本格式:header、method、url,其中httpMethod定义了http协议的所有方法:
public enum HttpMethod {
GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE
}
2. responseEntity继承自httpEntity定义了http响应的格式:header、body、status,其中HttpStatus是个枚举类,定义了1xx、2xx、3xx、4xx、5xx的响应状态码
3. MediaType继承自MimeType,定义了可以接受的请求文件类型。
http client
1. ClientHttpRequest是客户端请求的接口,它的抽象类是AbstractClientHttpRequest;SimpleStreamingClientHttpRequest(使用jkd自带的功能执行流处理请求)、HttpComponentsStreamingClientHttpRequest(使用apache的components组件来处理请求)、AbstractBufferingClientHttpRequest(抽象buffer)继承自AbstractClientHttpRequest抽象类;BufferingClientHttpRequestWrapper(简单的ClientRequest实现)、HttpComponentsClientHttpRequest(apache components组件的请求处理实现)、SimpleBufferingClientHttpRequest(使用jdk自带功能的http请求处理实现)继承自抽象类AbstractBufferingClientHttpRequest。
从上面的图中可以清晰的看出clientHttpRequest的族谱关系及其实现类。
2. ClientHttpResponse是客户端响应的接口,BufferingClientHttpResponseWrapper是ClientHttpResponse的简单实现,它读取request的body到内存中,因此支持多次触发getBody()方法;ClientHttpResponse的抽象类是AbstractClientHttpResponse;该抽象类有三个实现类,其中SimpleClientHttpResponse是使用jkd自带功能实现的,可以通过SimpleBufferingClientHttpRequest的execute()方法或者SimpleStreamingClientHttpRequest的execute()方法获取到该对象;HttpComponentsClientHttpResponse是使用apache components组件中HttpComponentsClientHttpRequest请求的返回对象;HttpComponentsAsyncClientHttpResponse是使用apache componets组件中HttpComponentsAsyncClientHttpRequest请求的返回对象。
3. 异步请求AsyncClientHttpRequest是接口,SimpleStreamingAsyncClientHttpRequest使用jdk自带功能实现的异步流处理请求,可以通过org.springframework.http.client.SimpleClientHttpRequestFactory的createRequest方法获取;AbstractBufferingAsyncClientHttpRequest是AsyncClientHttpRequest接口的抽象类,它在请求发送前将之缓存到一个byte数组中;SimpleBufferingAsyncClientHttpRequest是上述抽象类的实现类,它使用jkd自定的功能来执行缓存请求。可以通过org.springframework.http.client.SimpleClientHttpRequestFactory的createRequest方法获取该对象;
HttpComponentsAsyncClientHttpRequest是上述抽象类的实现类,它使用apache httpComponents组件的httpClient去执行request,该对象可以通过org.springframework.http.client.HttpComponentsClientHttpRequestFactory的createRequest方法去获取。
4. 异步响应HttpComponentsAsyncClientHttpResponse继承自AbstractClientHttpResponse抽象类,间接继承自ClientHttpResponse接口。
注意:请求request一般由请求工厂requestFactory来产生。
http server
1. ServletServerHttpRequest继承并实现了ServerHttpRequest接口,封装了HttpServletRequest,支持异步。
2. ServletServerHttpResponse继承并实现了ServerHttpResponse接口,封装了HttpServletResponse。
3. 异步的处理由ServletServerHttpAsyncRequestControl来完成,它继承并实现了ServerHttpAsyncRequestControl接口。它在response关闭前处理以异步方式处理httq请求。
http Converter
首先看一下它的层次结构图:

默认情况下,有如下一些HttpMessageConverter:
- ByteArrayHttpMessageConverter – 转换byte数组
- StringHttpMessageConverter – 转换string类型
- ResourceHttpMessageConverter – 转换任意类型的8位字节流到org.springframework.core.io.Resource
- SourceHttpMessageConverter – 转换 javax.xml.transform.Source
- FormHttpMessageConverter – 转换表单到/从MultiValueMap<String, String>类型.
- Jaxb2RootElementHttpMessageConverter – 转换java对象到/从xml格式(仅适用在classpath文件增加JAXB2 )
- MappingJackson2HttpMessageConverter – 转换JSON类型 (仅适用于clsspath中有jackson2)
- MappingJacksonHttpMessageConverter –转换JSON类型 (仅适用于clsspath中有jackson)
- AtomFeedHttpMessageConverter – 转换Atom feeds (仅适用于clsspath中有Rome)
- RssChannelHttpMessageConverter – 转换RSS feeds (仅适用于clsspath中有Rome)
小结:
spring-web是spring webmvc的基础,而spring-web的基础是spring-web http模块,它包含四个模块:
1. http 封装的基础如httpRequest、httpResponse、httpStatus、httpHeader等;
2. client端的request请求及响应;
3. server端的request请求及响应;
4. 格式的转换,如json,rss,xml等。
这个模块的学习可以结合http协议及servlet来学习,可以理解spring对http的封装是如何实现的。
spring源码分析之spring-web http详解的更多相关文章
- Spring源码分析:Spring IOC容器初始化
概述: Spring 对于Java 开发来说,以及算得上非常基础并且核心的框架了,在有一定开发经验后,阅读源码能更好的提高我们的编码能力并且让我们对其更加理解.俗话说知己知彼,百战不殆.当你对Spri ...
- ZRender源码分析5:Shape绘图详解
回顾 上一篇说到:ZRender源码分析4:Painter(View层)-中,这次,来补充一下具体的shape 关于热区的边框 以圆形为例: document.addEventListener('DO ...
- Jvm(jdk8)源码分析1-java命令启动流程详解
JDK8加载源码分析 1.概述 现在大多数互联网公司都是使用java技术体系搭建自己的系统,所以对java开发工程师以及java系统架构师的需求非常的多,虽然普遍的要求都是需要熟悉各种java开发框架 ...
- jQuery 源码分析(十八) ready事件详解
ready事件是当DOM文档树加载完成后执行一个函数(不包含图片,css等),因此它的触发要早于load事件.用法: $(document).ready(fun) ;fun是一个函数,这样当DOM树加 ...
- jQuery 源码分析(十一) 队列模块 Queue详解
队列是常用的数据结构之一,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).特点是先进先出,最先插入的元素最先被删除. 在jQuery内部,队列模块为动画模块提供基 ...
- vuex 源码分析(七) module和namespaced 详解
当项目非常大时,如果所有的状态都集中放到一个对象中,store 对象就有可能变得相当臃肿. 为了解决这个问题,Vuex允许我们将 store 分割成模块(module).每个模块拥有自己的 state ...
- Netty源码分析之Reactor线程模型详解
上一篇文章,分析了Netty服务端启动的初始化过程,今天我们来分析一下Netty中的Reactor线程模型 在分析源码之前,我们先分析,哪些地方用到了EventLoop? NioServerSocke ...
- spring源码分析之spring-web web模块分析
0 概述 spring-web的web模块是更高一层的抽象,它封装了快速开发spring-web需要的基础组件.其结构如下: 1. 初始化Initializer部分 1.1 Servlet3.0 的 ...
- 【spring源码分析】spring AspectJ的Execution表达式
在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execution (* com.sam ...
- Spring源码解析--IOC根容器Beanfactory详解
BeanFactory和FactoryBean的联系和区别 BeanFactory是整个Spring容器的根容器,里面描述了在所有的子类或子接口当中对容器的处理原则和职责,包括生命周期的一些约定. F ...
随机推荐
- 【js与jquery】电子邮箱、手机号、邮政编码的正则验证
//验证邮政编码 $("#postcode").blur(function(){ //获取邮政编码 var postcode=$("#postcode").va ...
- (转)INSTALLSHIELD 2010 预安装组件和软件
使用Installshield2010提供的组件 大家再开发软件产品的时候经常是基于某些软件和类库的,像我们的项目就用到了.Net Framework3.5,mapinfo,sqlserver 200 ...
- android ListView注意事项
所有问题,都是自己遇到过的. 但内容,有一半是自己写的,也有一半是复制过来. 所以,写成原创还请原谅 1. ListView添加标题后(addHeader())后,使用listView.getAdap ...
- HDU 5285 wyh2000 and pupil
题意:有一群人,已知某两人之间互相不认识,要把这群人分成两部分,每部分至少一人,且在每部分内没有人互不认识. 解法:图染色.某场bestcoder第二题……看完题觉得是个二分图……完全不会二分图什么的 ...
- Java was started but returned exit code=13 C:\ProgramData\Oracle\Java\javapath\javaw.exe
---------------------------Eclipse---------------------------Java was started but returned exit code ...
- 七牛上传Qt版本
最近在找图床,写博客啥的需要.以前的图床好像挂了,搭在BAE上的图床也挂了,可能BAE3.0更新了吧. 花了点时间写了Qt版本 github地址:https://github.com/wzyuliya ...
- C/C++:原码、反码和补码
正数的原码.反码和补码是一模一样的. 负数的反码的符号位跟原码一样,但其余各位取反. 负数的补码是其反码的最末位加1得到,即原码取反加1. 补码的补码就是原码. 浮点数的存储格式随着机器的 ...
- STM32 USB-HID通信移植步骤
大家可以使用压缩包中的UsbApp.exe调试本软件idVendor为:0483 idProduct为5750. 今天太晚了,明天还要上半天班,上位机软件找个时间在写一篇文章.请关注我的博客.压缩包 ...
- 恒天云技术分享系列4 – OpenStack网络攻击与防御
恒天云技术分享系列:http://www.hengtianyun.com/download-show-id-13.html 云主机的网络结构本质上和传统的网络结构一致,区别大概有两点. 1.软网络管理 ...
- Thinking in Java
今天无意中看到了这本书(Thinking in Java)的中关于多态的一段描述,瞬间就感觉到了多态原来是这样的.