Java Http請求工具類和接收請求的方法
阿新 • • 發佈:2018-12-27
表面現像上面看看GET和POST的區別:
1.GET請求的資料會附在URL之後(就是把資料放置在HTTP協議頭中),以?分割URL和傳輸資料,引數之間以&相連,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果資料是英文字母/數字,原樣傳送,如果是空格,轉換為+,如果是中文/其他字元,則直接把字串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號以16進製表示的ASCII。POST把提交的資料則放置在是HTTP包的包體中。
2."GET方式提交的資料最多隻能是1024位元組,理論上POST沒有限制,可傳較大量的資料,IIS4中最大為80KB,IIS5中為100KB"??!以上這句是我從其他文章轉過來的,其實這樣說是錯誤的,不準確的:
(1).首先是"GET方式提交的資料最多隻能是1024位元組",因為GET是通過URL提交資料,那麼GET可提交的資料量就跟URL的長度有直接關係了。 而實際上,URL不存在引數上限的問題,HTTP協議規範沒有對URL長度進行限制。這個限制是特定的瀏覽器及伺服器對它的限制。
(2).理論上講,POST是沒有大小限制的,HTTP協議規範也沒有進行大小限制,說“POST資料量存在80K/100K的大小限制”是不準確的,POST資料是沒有限制 的,起限制作用的是伺服器的處理程式的處理能力。對於ASP程式,Request物件處理每個表單域時存在100K的資料長度限制。但如果使用 Request.BinaryRead則沒有這個限制。 由這個延伸出去,對於IIS 6.0,微軟出於安全考慮,加大了限制。我們還需要注意:
1).IIS 6.0預設ASP POST資料量最大為200KB,每個表單域限制是100KB。
2).IIS 6.0預設上傳檔案的最大大小是4MB。
3).IIS 6.0預設最大請求頭是16KB。
IIS 6.0之前沒有這些限制。[具體參考
所以上面的80K,100K可能只是預設值而已(注:關於IIS4和IIS5的引數,我還沒有確認),但肯定是可以自己設定的。
由於每個版本的IIS對這些引數的預設值都不一樣,具體請參考相關的IIS配置文件。
此HTTPUtil工具類主要介紹怎麼傳送HTTP請求並附上獲取請求引數的兩種方式
import com.yjbq.common.StringUtil; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.util.Map; public class HttpUtil { private HttpUtil() { } /** * 傳送GET請求 * * @param url 傳送請求的URL * @param queryParas 引數集合 * @return */ public static String get(String url, Map<String, String> queryParas) { return get(url, queryParas, null); } /** * 傳送GET請求 * * @param url 傳送請求的URL * @return 所代表遠端資源的響應結果 */ public static String get(String url) { return get(url, null, null); } /** * 傳送GET請求 * * @param url 傳送請求的URL * @param queryParas 引數集合 * @param headers 頭集合 * @return 所代表遠端資源的響應結果 */ public static String get(String url, Map<String, String> queryParas, Map<String, String> headers) { HttpURLConnection conn = null; try { //獲取HttpURLConnection連線並設定引數 conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), "GET", headers); // 建立HttpURLConnection實際的連線 conn.connect(); //返回 定義BufferedReader輸入流來讀取URL的響應 return readResponseString(conn); } catch (Exception e) { throw new RuntimeException(e); } finally { if (conn != null) { conn.disconnect(); } } } /** * 傳送POST請求 * * @param url 傳送請求的URL * @param data http請求包的包體 * @param headers 頭集合 * @return 所代表遠端資源的響應結果 */ public static String post(String url, String data, Map<String, String> headers) { return post(url, null, data, headers); } /** * 傳送POST請求 * * @param url 傳送請求的URL * @param queryParas 請求引數(寫在url後面的引數)如http://www.baidu.com?state=1&data=233 * @param data http請求包的包體 * @param headers 頭集合 * @return */ public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) { HttpURLConnection conn = null; try { //獲取HttpURLConnection連線並設定引數 conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), "POST", headers); // 建立HttpURLConnection實際的連線 conn.connect(); // 獲取URLConnection物件對應的輸出流 OutputStream out = conn.getOutputStream(); // 傳送請求引數 out.write(data.getBytes("utf-8")); // flush輸出流的緩衝 out.flush(); //關閉輸出流 out.close(); //返回 定義BufferedReader輸入流來讀取URL的響應 return readResponseString(conn); } catch (Exception e) { throw new RuntimeException(e); } finally { if (conn != null) { conn.disconnect(); } } } /** * 獲取HttpURLConnection連線並設定引數 * * @param url 傳送請求的URL * @param method 請求方式(POST/GET) * @param headers 請求頭 * @return 所代表遠端資源的響應結果 * @throws IOException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws KeyManagementException */ private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException { //將url轉變為URL物件 URL _url = new URL(url); //開啟URL連線 HttpURLConnection conn = (HttpURLConnection) _url.openConnection(); //設定請求方式 conn.setRequestMethod(method); // 傳送POST請求必須設定如下兩行 conn.setDoOutput(true); conn.setDoInput(true); //連線時長 conn.setConnectTimeout(20000); //讀取時長 conn.setReadTimeout(60000); // 設定通用的請求屬性 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"); if (headers != null && !headers.isEmpty()) { for (Map.Entry<String, String> entry : headers.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); } } return conn; } /** * 將引數和URL地址拼接 * * @param url 傳送請求的URL如http://www.baidu.com {"state":"1","data":"拼接Url"} * @param queryParas 傳遞的引數 * @return */ private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) { if (queryParas == null || queryParas.isEmpty()) { return url; } StringBuilder sb = new StringBuilder(url); boolean isFirst; //判斷URL是否有 ? if (url.indexOf("?") == -1) { isFirst = true; sb.append("?"); } else { isFirst = false; } //遍歷請求引數 for (Map.Entry<String, String> entry : queryParas.entrySet()) { if (isFirst) { isFirst = false; } else { sb.append("&"); } String key = entry.getKey(); String value = entry.getValue(); if (!StringUtil.isNull(value)) { //對value進行轉碼 try { value = URLEncoder.encode(value, "utf-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } sb.append(key).append("=").append(value); } return sb.toString(); } /** * 讀取URL的響應 * * @param conn HttpURLConnection物件 * @return */ private static String readResponseString(HttpURLConnection conn) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; try { //獲取響應內容 inputStream = conn.getInputStream(); // 定義BufferedReader輸入流來讀取URL的響應 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8")); String line; while ((line = reader.readLine()) != null) { sb.append(line).append("\n"); } return sb.toString(); } catch (Exception e) { throw new RuntimeException(e); } // 使用finally塊來關閉輸入流 finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { } } } } }
測試類HttpTest中getRequestData()方法提供了獲取引數的兩種方式具體見程式碼(此程式碼用的是JFinal框架繼承了JFinal的Controller)並用到了fastjson-1.2.6.jar包。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.core.Controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletInputStream;
/**
*
* @author Administrator
*/
public class HttpTest extends Controller{
public void getTest(){
try {
String s = getRequestData();
System.out.println(s);
JSONObject json = JSONObject.parseObject(s);
System.out.println(json.getString("test"));
renderJson(s);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 獲取GET/POST請求提交的資料
* @return
*/
public String getRequestData(){
StringBuilder sb = new StringBuilder();
try{
//獲取Http請求包的包體有兩種方式getInputStream()、getReader(),因為GET方式請求一般不包含包體.一般用於POST請求獲取引數.
BufferedReader br = new BufferedReader(new InputStreamReader(getRequest().getInputStream()));
//BufferedReader br = new BufferedReader(getRequest().getReader());
String line;
while((line = br.readLine())!=null){
sb.append(line);
}
}catch(IOException e){
System.out.println("getPostData Error: " + e.getLocalizedMessage());
e.printStackTrace();
}
//如果包體沒有值則獲取url後面的引數
if(sb.length() != 0){
return sb.toString();
}else{
JSONObject json = new JSONObject();
//JFinal獲取url引數的方法
Enumeration<String> names = getRequest().getParameterNames();
//遍歷引數
while(names.hasMoreElements()){
String key = names.nextElement();
json.put(key, getPara(key));
}
return json.toString();
}
}
public static void main(String[] args){
Map<String, String> params = new HashMap<String, String>();
params.put("num", "201");
params.put("name", "李明");
params.put("phone", "176****1828");
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json;charset=UTF-8");
//請求引數附在URL後面的請求方式
//String result = HttpUtil.post("http://地址:埠/httpTest/getTest", params, "", headers);
//請求引數放在HTTP包的包體中
String result = HttpUtil.post("http://地址:埠/httpTest/getTest",JSON.toJSONString(params),headers);
System.out.println(result);
}
}