序言
之前我發的一篇[Http Get與Post函式]中已經實現了可維持Session狀態的HTTP連線函式,但我發現了Apache提供的這個Client在Windows下會有連線數上限的問題(聽說好像調整XP連線數可以解決)。另外,有的時候使用HTTP連線也不一定需要維持Session狀態,這時候其實就不需要另外加入Apache的http client的JAR。
因此我還是整理一下如果一個不維持Session狀態的HTTP Client連線怎麼達成。
函式原始碼
參數轉換函式package common.control;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
public class HTTPParseFunc {
/**
* hashMapToString
*
* @param map
* @param charset編碼
* ,如HTTP.UTF_8
* @return
* @throws UnsupportedEncodingException
*/
@SuppressWarnings("unchecked")
public static String hashMapToString(HashMap<String, String> map,
String charset) throws UnsupportedEncodingException {
StringBuffer result = new StringBuffer();
java.util.Iterator it = map.entrySet().iterator();
boolean isfirst = true;
while (it.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
if (isfirst) {
isfirst = false;
} else {
result.append("&");
}
result
.append(URLEncoder.encode(entry.getKey().toString(),
charset));
result.append("=");
result.append(URLEncoder.encode(entry.getValue().toString(),
charset));
}
return result.toString();
}
/**
* 將inputStream轉為String
*
* @param is
* inputStream
* @param charset
* 編碼,如HTTP.UTF_8
* @return inputStream的內容
* @throws UnsupportedEncodingException
*/
public static String inputStream2String(InputStream is, String charset)
throws UnsupportedEncodingException {
BufferedReader in = new BufferedReader(new InputStreamReader(is,
charset));
StringBuffer buffer = new StringBuffer();
String line = "";
try {
boolean isfirst = true;
while ((line = in.readLine()) != null) {
if (!isfirst) {
buffer.append("\n");
} else {
isfirst = false;
}
buffer.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
/**
* HTTP 傳輸參數分割
* @param param 如name1=value1&name2=value2
* @return
* @throws UnsupportedEncodingException
*/
public static ArrayList<String[]> paramToArray(String param)
throws UnsupportedEncodingException {
ArrayList<String[]> arr = null;
String[] p = param.split("&");
if (param.toLowerCase().contains("&")) {
ArrayList<String> p2 = new ArrayList<String>();
int j = 0;
for (int i = 0; i < p.length; i++) {
if (p[i].toLowerCase().startsWith("amp;")) {
p2.set(j - 1, p2.get(j - 1) + "&" + p[i].substring(4));
j--;
}
p2.add(p[i]);
j++;
}
p2.toArray(p);
}
for (int i = 0; i < p.length; i++) {
String[] item = p[i].split("=");
if (item.length == 2) {
if (arr == null)
arr = new ArrayList<String[]>();
// item[0]=URLDecoder.decode(item[0],charset);
// item[1]=URLDecoder.decode(item[1],charset);
arr.add(item);
}
}
return arr;
}
}
連線參數模型package common.model;
public class HTTPResponse {
String html=null;
Integer statusCode=null;
public String getHtml() {
return html;
}
public void setHtml(String html) {
this.html = html;
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
}
HTTP連線函式
package common;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.util.HashMap;
import common.control.HTTPParseFunc;
import common.model.HTTPResponse;
public class HTTPBaseIO2 {
public enum Method {
get, post
}
/**
* 送出Request
* @param urlpath URL
* @param method HTTPBaseIO2.Method.get/post
* @param params HashMap<Name, Value>
* @param charset UTF-8
* @param timeout 連線逾時null:不設限/millisecond
* @return 回傳的html
* @throws UnsupportedEncodingException
*/
public static HTTPResponse doSend(String urlpath, Method method,
HashMap<String, String> params, String charset,boolean isAutoRedirect, Integer timeout,Proxy proxy) throws UnsupportedEncodingException {
HTTPResponse result=new HTTPResponse();
String param=null;
if(params!=null){
param=HTTPParseFunc.hashMapToString(params, charset);
}
if(method==Method.post){
result=sendPost(urlpath,param,charset,isAutoRedirect,timeout,proxy);
}else{
result=sendGet(urlpath,param,charset,isAutoRedirect,timeout,proxy);
}
return result;
}
/**
* 向指定URL發送GET方法的請求
*
* @param url
* 發送請求的URL
* @param param
* 請求參數,請求參數應該是name1=value1&name2=value2的形式。
* @return URL所代表遠程資源的響應
*/
public static HTTPResponse sendGet(String url, String params, String charset,boolean isAutoRedirect, Integer timeout,Proxy proxy) {
HTTPResponse result=new HTTPResponse();
HttpURLConnection conn=null;
BufferedReader in = null;
try {
String urlName = url;
if(params!=null) urlName+= "?" + params;
URL realUrl = new URL(urlName);
HttpURLConnection.setFollowRedirects(isAutoRedirect);
// 打開和URL之間的連接
if(proxy!=null)
conn = (HttpURLConnection)realUrl.openConnection(proxy);
else
conn = (HttpURLConnection)realUrl.openConnection();
if(timeout!=null) conn.setConnectTimeout(timeout);
// 設置通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 建立實際的連接
conn.connect();
result.setHtml(HTTPParseFunc.inputStream2String(conn.getInputStream(), charset));
} catch (Exception e) {
e.printStackTrace();
result=null;
}
// 使用finally塊來關閉輸入流
finally {
try {
if (conn != null){
if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK)
result=null;
result.setStatusCode(conn.getResponseCode());
}
} catch (Exception e) {
}
try {
if (in != null) {
in.close();
}
if (conn != null){
conn.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
/**
* 向指定URL發送POST方法的請求
*
* @param url
* 發送請求的URL
* @param param
* 請求參數,請求參數應該是name1=value1&name2=value2的形式。
* @return URL所代表遠程資源的響應
*/
public static HTTPResponse sendPost(String url, String params, String charset,boolean isAutoRedirect, Integer timeout,Proxy proxy) {
HTTPResponse result=new HTTPResponse();
PrintWriter out = null;
BufferedReader in = null;
HttpURLConnection conn=null;
try {
URL realUrl = new URL(url);
// 打開和URL之間的連接
HttpURLConnection.setFollowRedirects(isAutoRedirect);
if(proxy!=null)
conn = (HttpURLConnection)realUrl.openConnection(proxy);
else
conn = (HttpURLConnection)realUrl.openConnection();
if(timeout!=null) conn.setConnectTimeout(timeout);
// 設置通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 發送POST請求必須設置如下兩行
conn.setDoOutput(true);
conn.setDoInput(true);
// 獲取URLConnection對象對應的輸出流
out = new PrintWriter(conn.getOutputStream());
// 發送請求參數
if(params!=null) out.print(params);
// flush輸出流的緩衝
out.flush();
result.setHtml(HTTPParseFunc.inputStream2String(conn.getInputStream(), charset));
} catch (Exception e) {
e.printStackTrace();
result=null;
}
// 使用finally塊來關閉輸出流、輸入流
finally {
try {
if (conn != null){
if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK)
result=null;
result.setStatusCode(conn.getResponseCode());
}
} catch (Exception e) {
}
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
if (conn != null){
conn.disconnect();
}
}
return result;
}
}
使用範例程式
package common.test;
import java.util.HashMap;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import common.HTTPBaseIO2;
import common.model.HTTPResponse;
public class HTTPBaseIO2Test {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testDoGet() {
String urltest = "http://localhost:8080/Test/Test1" ;
String charset="UTF-8";
HashMap<String, String> params=new HashMap<String, String>();
try {
params.put("val", "測試&測試");
HTTPResponse html=HTTPBaseIO2.doSend(urltest, HTTPBaseIO2.Method.get, params, charset,true,null,null);
System.out.println("testDoGet:"+html.getHtml());
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testDoPost() {
String urltest = "http://localhost:8080/Test/Test1" ;
String charset="UTF-8";
HashMap<String, String> params=new HashMap<String, String>();
try {
params.put("val", "測試1&測試1");
HTTPResponse html=HTTPBaseIO2.doSend(urltest, HTTPBaseIO2.Method.post, params, charset,true,null,null);
System.out.println("testDoPost:"+html.getHtml());
params.clear();
params.put("val", "測試2&測試2");
html=HTTPBaseIO2.doSend(urltest, HTTPBaseIO2.Method.post, params, charset,true,null,null);
System.out.println("testDoPost:"+html.getHtml());
} catch (Exception e) {
e.printStackTrace();
}
}
}