日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单封装 HTTP 请求

發(fā)布時間:2025/7/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单封装 HTTP 请求 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2017-2-19 更新到第二版:

源碼地址:http://git.oschina.net/sp42/ajaxjs/tree/master/ajaxjs-base/src/com/ajaxjs/net?dir=1&filepath=ajaxjs-base%2Fsrc%2Fcom%2Fajaxjs%2Fnet

和文件操作一樣,其內(nèi)部使用了鏈式風(fēng)格的調(diào)用方式。

GET/HEAD 請求

GET 請求用法參見下面的測試用例,包括普通 GET 請求、獲取 302 重定向調(diào)轉(zhuǎn)地址、獲取資源文件體積大小、是否 404以及下載二進制文件等功能。

System.out.println(Client.GET("https://www.baidu.com/"));// 獲取資源文件體積大小 long size = Client.getFileSize("http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png"); assertEquals(size, 4102L); // 獲取 302 重定向跳轉(zhuǎn)地址 System.out.println(Client.get302redirect("https://baidu.com")); // 封裝 head 請求檢測是否 404 assertTrue(!Client.is404("http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png")); // B 站強制 Gzip 返回,無論請求是否帶有 GZIP 字段 System.out.println(Client.GET_Gzip("http://www.bilibili.com/video/av5178498/")); POST 請求
String url = "http://localhost:8080/pachong/post.jsp"; String result = Client.POST(url, new HashMap<String, Object>() {private static final long serialVersionUID = 1L;{put("foo", "bar");} }); System.out.println("Feedback:" + result);

2016-7-12 : 新增 GZip 請求和 Gzip 響應(yīng)判斷。

請求判斷

if(request.isEnableGzip()) // 是否啟動 GZip 請求connection.addRequestProperty("Accept-Encoding", "gzip, deflate");

一般情況下,請求頭加入了上面的 Accept-Encoding 字段,服務(wù)器才會對內(nèi)容進行 GZip 壓縮,否則就不壓縮,原文輸出。但有些網(wǎng)站是不管有沒有這種請求都一概返回 GZIP 的。如果有 GZIP,服務(wù)器會告訴我們的,在響應(yīng)頭中加入 Content-Encoding 的字段。響應(yīng)判斷:

// 是否啟動 GZip 請求// 有些網(wǎng)站強制加入 Content-Encoding:gzip,而不管之前的是否有 GZip 的請求boolean isGzip = request.isEnableGzip() || "gzip".equals(connection.getHeaderField("Content-Encoding"));

如果不對 Gzip 的內(nèi)容進行 GZipInputStream 處理會一段亂碼。

測試用例:

@Testpublic void testGZipGet() {Request request = new Request();request.setUrl("http://u.3gtv.net");request.setEnableGzip(true);RequestClient rc = new RequestClient(request);try {rc.connect();} catch (ConnectException e) {System.out.println("請求出錯" + request.getUrl());}String html = request.getFeedback();System.out.println(html);assertNotNull(html);}// B 站強制 Gzip 返回,無論請求是否帶有 GZIP@Testpublic void testForce_GZipGet() {String url = "http://www.bilibili.com/video/av5178498/";String html = Get.GET(url);System.out.println(html);assertNotNull(html);}

-------------------------------------------------------------------------------------------------------------

簡單封裝 Java 類庫里面的 HttpURLConnection 來完成日常的 HTTP 請求,如 GET、HEAD、POST 等的請求。

GET 請求用法參見下面的測試用例,包括普通 GET 請求、獲取 302 重定向調(diào)轉(zhuǎn)地址、獲取資源文件體積大小、是否 404以及下載二進制文件等功能。

import static org.junit.Assert.*; import org.junit.Test;import java.io.IOException;import com.ajaxjs.net.http.Get; import com.ajaxjs.util.FileUtil;public class TestGet {@Testpublic void testSimpleGET() {String url = "https://baidu.com";String html = Get.simpleGET(url);System.out.println(html);assertNotNull(html);}@Testpublic void testGet() {String url = "https://baidu.com";String html = Get.GET(url);System.out.println(html);assertNotNull(html);}@Testpublic void testGet302redirect() {String url = "http://baidu.com";String location = Get.get302redirect(url);System.out.println(location);assertNotNull(location);}@Testpublic void testIs404() {String url = "http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png";assertTrue(!Get.is404(url));assertTrue(Get.is404("http://www.qq.com/54543"));}@Testpublic void testGetFileSize() {String url = "http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png";long size = Get.getFileSize(url);assertEquals(size, 4102L);}@Testpublic void testDownload2disk() throws IOException {String url = "http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png";Get.download2disk(url, "c:/temp/dd.png");String saveTo = "c:/temp/js.js";Get.download2disk("http://bdimg.share.baidu.com/static/api/js/base/tangram.js?v=37768233.js", saveTo);assertNotNull(FileUtil.readFileAsText(saveTo));}}

Get.simpleGET 和 Get.GET 用法一致,傳入 url 參數(shù),返回該網(wǎng)址的文本內(nèi)容。具體不同可能要看看源碼。simpleGET 是原始 API 版, 一句話完事的:new URL(url).openStream(),然后把字符流轉(zhuǎn)為 text 即可。Get.GET 也是字符流轉(zhuǎn)為 text,只是前期處理上不是調(diào) API,為自己實現(xiàn)邏輯,遵循了 bean 方式的調(diào)用。這種方式在咱們這個 HTTP 庫里面的是通用方式。首先 Request 類是一個 Java bean,定義了請求地址 HTTP Url、請求方法 HTTP Mehtod,還有若干常見的 HTTP 頭,都做成了 getter/setter,使用者按照 Request 類的方法調(diào)用即可。其次 GET 請求和 POST 請求本身就差別不少,因此劃分為 Get/Post 兩個類。但實際發(fā)出請求的是 RequestClient 類。這個類是不管哪種請求的,都是圍繞后期 HTTP 響應(yīng)作處理,主要是流的處理,以及一些諸如 404、超時異常的處理。下面是 RequestClient 源碼:

import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; import java.net.UnknownHostException;import com.ajaxjs.util.FileUtil; import com.ajaxjs.util.StringUtil;import sun.misc.BASE64Encoder;/*** 發(fā)起 HTTP 請求* @author frank**/ public class RequestClient {/*** 請求目標(biāo)地址*/private URL url;/*** API 鏈接對象*/private HttpURLConnection connection;/*** 攜帶請求信息的 Bean*/private Request request;/*** 創(chuàng)建 HTTP 請求* * @param request* 請求信息對象*/public RequestClient(Request request) {this.request = request;try {url = new URL(request.getUrl());connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod(request.getMethod());} catch (IOException e) {System.err.println("初始化連接出錯!" + request.getUrl());e.printStackTrace();}}/*** 內(nèi)部初始化*/private void init() {connection.addRequestProperty("User-Agent", request.getUserAgent());connection.addRequestProperty("Referer", request.getUrl() == null ? url.getHost() : request.getUrl());connection.setConnectTimeout(request.getTimeout() * 1000);// 設(shè)置超時// connection.setReadTimeout(30000);if (request.getCookies() != null) {String cookieStr = StringUtil.HashJoin(request.getCookies(), ";");connection.setRequestProperty("Cookie", cookieStr);}if (request.getBasicAuthorization() != null) { // HTTP 用戶認證String username = request.getBasicAuthorization()[0], password = request.getBasicAuthorization()[1];String encoding = new BASE64Encoder().encode((username + ":" + password).getBytes());connection.setRequestProperty("Authorization", "Basic " + encoding);}}/*** 發(fā)起請求* * @return true 表示為發(fā)起請求成功* @throws ConnectException*/public boolean connect() throws ConnectException {init();// 寫入數(shù)據(jù)(POST ONLY, GET 不需要)if (request.getWriteData() != null && !request.getMethod().equalsIgnoreCase("GET")) {// 寫入 POST 數(shù)據(jù)try (OutputStream os = connection.getOutputStream()) {os.write(request.getWriteData());os.flush();} catch (IOException e) {e.printStackTrace();return false;}}// 接受響應(yīng)try (InputStream is = connection.getInputStream();) {if (connection.getResponseCode() >= 400) {// 如果返回的結(jié)果是400以上,那么就說明出問題了ConnectException e = null;if (connection.getResponseCode() < 500) {e = new ConnectException(connection.getResponseCode() + ":客戶端請求參數(shù)錯誤!");} else {e = new ConnectException(connection.getResponseCode() + ":抱歉!我們服務(wù)端出錯了!");}String msg = FileUtil.readText(is);e.setFeedback(msg);if (request.isTextResponse())request.setFeedback(msg);throw e;}if (request.getCallback() != null) {request.getCallback().onDataLoad(is);}if (request.isTextResponse())request.setFeedback(FileUtil.readText(is));} catch (UnknownHostException e) {throw new ConnectException("未知地址!" + request.getUrl());} catch (FileNotFoundException e) {throw new ConnectException("404 地址!" + request.getUrl());} catch (SocketTimeoutException e) {throw new ConnectException("請求地址超時!" + request.getUrl());} catch (IOException e) {try {System.out.println(connection.getResponseCode());} catch (IOException e1) {e1.printStackTrace();}throw new ConnectException("請求地址 IO 異常!" + request.getUrl());}return true;} public URL getUrl() {return url;}public void setUrl(URL url) {this.url = url;}public Request getRequest() {return request;}public void setRequest(Request request) {this.request = request;}public HttpURLConnection getConnection() {return connection;}public void setConnection(HttpURLConnection connection) {this.connection = connection;}}
其他源碼就不張貼了,有興趣的可以到這里看全部源碼。

POST 例子不多,先放一個:

String url = "http://localhost:8080/pachong/post.jsp"; Request request = Post.POST(url, new HashMap<String, Object>() {private static final long serialVersionUID = 1L;{put("foo", "bar");} }); System.out.println("Feedback:" + request.getFeedback()); assertNotNull(request); assertTrue(request.isDone());
代碼比較簡單,應(yīng)該沒有什么晦澀的地方。請大家多給給意見。

總結(jié)

以上是生活随笔為你收集整理的简单封装 HTTP 请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。