最近接触到Http请求的应用,在对高手的示例和网上资料的理解下,做一个总结:
1. Http的介绍:
a. request
b. response
2. Java实现一个http的请求的示例
3. 附录:request,response的Header,状态响应码
1.Http的介绍
HTTP(HyperTextTransferProtocol) 即超文本传输协议,目前网页传输的的通用协议。HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应。就整个网络资源传输而 言,包括message-header和message-body两部分。
a. request
通过连接,客户端写一个ASCII文本请求行,后跟0或多个HTTP头标,一个空行和实现请求的任意数据。
一个请求由四个部分组成:请求行、请求头标、空行和请求数据
1.请求行:请求行由三个标记组成:请求方法、请求URI和HTTP版本,它们用空格分隔
例如:GET /index.html HTTP/1.1HTTP规范定义了8种可能的请求方法:
GET 检索URI中标识资源的一个简单请求
HEAD 与GET方法相同,服务器只返回状态行和头标,并不返回请求文档
POST 服务器接受被写入客户端输出流中的数据的请求
PUT 服务器保存请求数据作为指定URI新内容的请求
DELETE 服务器删除URI中命名的资源的请求
OPTIONS 关于服务器支持的请求方法信息的请求
TRACE Web服务器反馈Http请求和其头标的请求
CONNECT 已文档化但当前未实现的一个方法,预留做隧道处理
2.请求头标:由关键字/值对组成,每行一对,关键字和值用冒号(:)分隔。请求头标通知服务器有关于客户端的功能和标识,典型的请求头标有:
User-Agent 客户端厂家和版本
Accept 客户端可识别的内容类型列表
Content-Length 附加到请求的数据字节数
3.空行:最后一个请求头标之后是一个空行,发送回车符和退行,通知服务器以下不再有头标。
4.请求数据:使用POST传送数据,最常使用的是Content-Type和Content-Length头标。
b. response
Web服务器解析请求,定位指定资源。服务器将资源副本写至套接字,在此处由客户端读取。
一个响应由四个部分组成;状态行、响应头标、空行、响应数据
1.状态行:状态行由三个标记组成:HTTP版本、响应代码和响应描述。
HTTP版本:向客户端指明其可理解的最高版本。
响应代码:3位的数字代码,指出请求的成功或失败,如果失败则指出原因。
响应描述:为响应代码的可读性解释。
例如:HTTP/1.1 200 OK
HTTP响应码:
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误:
2.响应头标:像请求头标一样,它们指出服务器的功能,标识出响应数据的细节。
3.空行:最后一个响应头标之后是一个空行,发送回车符和退行,表明服务器以下不再有头标。
4.响应数据:HTML文档和图像等,也就是HTML本身。
2. Java实现一个http的请求的示例
服务端:(servlet需要在web.xml中配置)
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author WangW
*
*/
public class HttpServerServlet extends HttpServlet {
private static final long serialVersionUID = 6393127207954048974L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置头信息,在客户端请求的时候就可以得到这个信息
response.setHeader("headTest", "valueTest");
PrintWriter out = response.getWriter();
String param = request.getParameter("parameter");
System.out.println(param);
out.println(param);
/**
* 如果是流的请求方式,用下面的代码
*/
// response.setContentType("text/xml");
// response.setCharacterEncoding("UTF-8");
//
// System.out.println("----------------------");
// InputStreamReader reader = new
// InputStreamReader(request.getInputStream(), "UTF-8");
// char[] buff = new char[1024];
// int length = 0;
// while ((length = reader.read(buff)) != -1) {
// String x = new String(buff, 0, length);
// System.out.println(x);
// out.print(x);
// }
}
}
带参数名的请求方式:
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
/**
* @author WangW
*
*/
public class ClientMainParam {
public static void main(String[] args) throws UnsupportedEncodingException, IllegalStateException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:8080/HttpServerTest/servlet/HttpServerServlet");
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("parameter", "这是中文参数"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, HTTP.UTF_8);
// entity.setContentType("text/xml; charset=GBK");
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() == 200){
Header[] header = response.getAllHeaders();
for (Header header2 : header) {
System.out.println(header2);
}
HttpEntity resEntity = response.getEntity();
String jsonResult = EntityUtils.toString(resEntity);
System.out.println(jsonResult);
}
// 流读取方式
// InputStreamReader reader = new InputStreamReader(resEntity.getContent(), HTTP.UTF_8);
// char[] buff = new char[1024];
// int length = 0;
// while ((length = reader.read(buff)) != -1) {
// System.out.println(new String(buff, 0, length));
// httpclient.getConnectionManager().shutdown();
// }
}
}
不带参数名的请求方式:
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.*;
import java.io.IOException;
public class ClientMainNoParam {
public static void main(String[] args) throws IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:8080/HttpServerTest/servlet/HttpServerServlet");
StringEntity myEntity = new StringEntity("这时中文参数", "UTF-8");
httppost.addHeader("Content-Type", "text/xml");
httppost.setEntity(myEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
if (response.getStatusLine().getStatusCode() == 200) {
Header[] header = response.getAllHeaders();
for (Header header2 : header) {
System.out.println(header2);
}
String jsonResult = EntityUtils.toString(resEntity);
System.out.println(jsonResult);
}
httpclient.getConnectionManager().shutdown();
}
}
客户端需要的包:
3.附录:
Response部分:
Accept-Ranges | 表明服务器是否支持指定范围请求及哪种类型的分段请求 | Accept-Ranges: bytes | |||
Age | 从原始服务器到代理缓存形成的估算时间(以秒计,非负) | Age: 12 | |||
Allow | 对某网络资源的有效的请求行为,不允许则返回405 | Allow: GET, HEAD | |||
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型 | Cache-Control: no-cache | |||
Content-Encoding | web服务器支持的返回内容压缩编码类型。 | Content-Encoding: gzip | |||
Content-Language | 响应体的语言 | Content-Language: en,zh | |||
Content-Length | 响应体的长度 | Content-Length: 348 | |||
Content-Location | 请求资源可替代的备用的另一地址 | Content-Location: /index.htm | |||
Content-MD5 | 返回资源的MD5校验值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== | |||
Content-Range | 在整个返回体中本部分的字节位置 | Content-Range: bytes 21010-47021/47022 | |||
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 | |||
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT | |||
ETag | 请求变量的实体标签的当前值 | ETag: “737060cd8c284d8af7ad3082f209582d” | |||
Expires | 响应过期的日期和时间 | Expires: Thu, 01 Dec 2010 16:00:00 GMT | |||
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT | |||
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 | Location: http://www.zcmhi.com/archives/94.html | |||
Pragma | 包括实现特定的指令,它可应用到响应链上的任何接收方 | Pragma: no-cache | |||
Proxy-Authenticate | 它指出认证方案和可应用到代理的该URL上的参数 | Proxy-Authenticate: Basic | |||
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) | Refresh: 5; url= http://www.zcmhi.com/archives/94.html | |||
Retry-After | 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 | Retry-After: 120 | |||
Server | web服务器软件名称 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) | |||
Set-Cookie | 设置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 | |||
Trailer | 指出头域在分块传输编码的尾部存在 | Trailer: Max-Forwards | |||
Transfer-Encoding | 文件传输编码 | Transfer-Encoding:chunked | |||
Vary | 告诉下游代理是使用缓存响应还是从原始服务器请求 | Vary: * | |||
Via | 告知代理客户端响应是通过哪里发送的 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) | |||
Warning | 警告实体可能存在的问题 | Warning: 199 Miscellaneous warning | |||
WWW-Authenticate | 表明客户端请求实体应该使用的授权方案 | WWW-Authenticate: Basic | |||
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded | |||
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT | |||
Expect | 请求的特定的服务器行为 | Expect: 100-continue | |||
From | 发出请求的用户的Email | From: user@email.com | |||
Host | 指定请求的服务器的域名和端口号 | Host: www.zcmhi.com | |||
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” | |||
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT | |||
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” | |||
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” | |||
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT | |||
Max-Forwards | 限制信息通过代理和网关传送的时间 | Max-Forwards: 10 | |||
Pragma | 用来包含实现特定的指令 | Pragma: no-cache | |||
Proxy-Authorization | 连接到代理的授权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== | |||
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 | |||
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: http://www.zcmhi.com/archives/71.html | |||
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers,deflate;q=0.5 | |||
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 | |||
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) | |||
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) | |||
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
Request部分:
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
响应码含义:
100 继续
101 分组交换协
200 OK
201 被创建
202 被采纳
203 非授权信息
204 无内容
205 重置内容
206 部分内容
300 多选项
301 永久地传送
302 找到
303 参见其他
304 未改动
305 使用代理
307 暂时重定向
400 错误请求
401 未授权
402 要求付费
403 禁止
404 未找到
405 不允许的方法
406 不被采纳
407 要求代理授权
408 请求超时
409 冲突
410 过期的
411 要求的长度
412 前提不成立
413 请求实例太大
414 请求URI太大
415 不支持的媒体类型
416 无法满足的请求范围
417 失败的预期
500 内部服务器错误
501 未被使用
502 网关错误
503 不可用的服务
504 网关超时
505 HTTP版本未被支持
引用内容:
http://www.iteye.com/topic/1118531
http://lavasoft.blog.51cto.com/62575/347157
参考资料:
http://blog.csdn.net/tongdoudpj/article/details/2619403
http://www.jiucool.com/java-sending-http-requests-get-and-post-method-request/
http://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE