2013/03/08

使用 HttpURLConnection Post

使用 HttpURLConnection 做 Post 基本上很簡單, 可以透過以下方式達成, 以下都沒有做 Exception 或者 Error 處理.
StringBuilder uriparameters = new StringBuilder();
uriparameters.append("user=" + URLEncoder.encode(user, "UTF-8"));
uriparameters.append("&password="+ URLEncoder.encode(pass, "UTF-8"));
int parameterLen = uriparameters.length();
/** sURL 是想要 post 的網址 **/
URL url = new URL(sURL);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();

/** 假裝成瀏覽器 **/
conn.setRequestProperty(
  "User-Agent",
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11");
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
conn.setRequestMethod("POST");

conn.setRequestProperty("X-Gallery-Request-Method", "post");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(paramsLen));

conn.setDoOutput(true);
conn.setDoInput(true);

DataOutputStream wr = null;
wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(uriparameters.toString());
wr.flush();
wr.close();
wr = null;
/** 取得 post 後所得到的 response **/
InputStream in = conn.getInputStream();
但是萬一是要上傳檔案呢 ? 這就不是這麼簡單了, 但是一樣可以用類似的方式達成我們的目的. 其實主要就是我們必須要自己去把整個post body 自己寫上去, 如果不知道怎麼寫, 簡單方式就是透過 wireshark 抓取自己透過瀏覽器上傳的封包, 接著再把封包內容寫上去這樣就好了.
final String POST_CRLF    = "\r\n";
final String POST_TWO_HYPHENS  = "--";
final String POST_BOUNDARY   =  "*****";
final String POST_UPLOAD          = POST_TWO_HYPHENS+POST_BOUNDARY+POST_CRLF;
final String POST_UPLOAD_END   = POST_CRLF+POST_TWO_HYPHENS+POST_BOUNDARY+POST_TWO_HYPHENS+POST_CRLF;

URL url = new URL(sURL);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();

conn.setRequestProperty(
  "User-Agent",
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11");
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("X-Gallery-Request-Method", "post");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + Const.POST_BOUNDARY);


conn.setDoOutput(true);
conn.setDoInput(true);

DataOutputStream wr = new DataOutputStream(conn.getOutputStream());

wr.writeBytes(Const.POST_UPLOAD);
wr.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"");
wr.write(f.getName().getBytes("UTF-8"));
wr.writeBytes("\"" + Const.POST_CRLF);
wr.writeBytes("Content-Type: application/octet-stream" + Const.POST_CRLF);
wr.writeBytes(Const.POST_CRLF);

BufferedInputStream bin = new BufferedInputStream(fin);
byte[] rdata = new byte[4096];
int count = 0;
/** total upload length **/
int ulen = 0;

while ((count = bin.read(rdata)) != -1) {
 ulen += count;
 wr.write(rdata, 0, count);
}
wr.writeBytes(Const.POST_UPLOAD_END);
wr.flush();
wr.close();
wr = null;

InputStrem in = conn.getInputStream();