java中处理header请求以及跟cookie相关的一些细节

服务端是否在cookie中返回phpsessionid取决于处理该页面请求的脚本是否调用了session_start(),不管是服务端返回cookie给客户端,还是客户端返回cookie给服务端,都是在header中保存的,而header的本质其实是几行用冒号:分割的键值对。如下的get请求:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Cookie:bdshare_firstime=1394693898320; Hm_lvt_2f2ac530df20294f718580cea710780e=1396330354,1396332063,1396332065,1396402453; Hm_lpvt_2f2ac530df20294f718580cea710780e=1396404308
Host:jcodecraeer.com
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36

上面的请求头中,我们可以看到cookie不同变量之间是用分号间隔的,没有包含phpsessionid。在某些处理http协议的java包中,可以看到对header的生成提供了专门的方法,类似于addHeader()这样的,有的还封装了专门针对cookie的方法,搞得好像cookie和header是两码事,我在用org.apache.http的时候都被搞晕了。http协议很简单,能放数据的地方真的不多,那些额外的数据几乎都是放在header中。

所以我还是觉得在使用那些看似方便的包之前还是从最基础的java.net.HttpURLConnection来实现http联网操作。

使用java.net


使用java.net一般只需引入两个类就可以了:

import java.net.HttpURLConnection;
import java.net.URL;

准备

首先你需要一个url,以及字符集charset,url后面的参数为可选的。如下在代码中先定义url、字符集以及由两个参数param1,`param2`组成的查询参数。

String url = "http://example.com";
String charset = "UTF-8";
String param1 = "value1";
String param2 = "value2";
// ...
String query = String.format("param1=%s&param2=%s",
     URLEncoder.encode(param1, charset),
     URLEncoder.encode(param2, charset));

查询参数都是有name=value这种形式组成的不同的name=value
之间用&分割。参数可以用 URL-encode指定字符集,

发起一个get请求

代码如下:

URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...

在url与查询条件之间需要用‘?’连接请求头```Accept-Charset暗示服务器传入的参数是何种字符集,如果你根本没有参数,可以不用在header中保留`` `Accept-Charset` ``一项。如果你连header都不需要,发起一个get请求甚至可以简化成这样:```

InputStream response = new URL(url).openStream();
// ...

实际上发出get请求我们还需要指定method为get

connection.setRequestMethod("GET");

但是默认请求就是get的因此上面那行代码也可以不要。

发起post请求

URLConnection#setDoOutput()设置为true则意味着请求是post的,即使调用了

connection.setRequestMethod("GET");

setDoOutput(true)会使`setRequestMethod(``"GET"``)无效。`

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
OutputStream output = connection.getOutputStream();
try {
     output.write(query.getBytes(charset));
} finally {
     try { output.close(); } catch (IOException logOrIgnore) {}
}
InputStream response = connection.getInputStream();
// ...