多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > HttpUrlConnection get和post簡單實現(疑惑解決)

HttpUrlConnection get和post簡單實現(疑惑解決)

來源:程序員人生   發布時間:2014-11-25 08:48:13 閱讀次數:3372次

最近研究微信的公眾平臺開發,需要和微信的http://www.vxbq.cn/server/進行數據讀取,簡單研究了下jdk自帶的HttpUrlConnection類(URLConnection的子類),簡單實現了1下微信的http://www.vxbq.cn/access/_token獲得。

獲得微信http://www.vxbq.cn/access/_token的地址:微信地址

該地址是get方法要求便可,先貼代碼,doGet:

private final String ACCESS_TOKEN_WEIXIN = "https://api.weixin.qq.com/cgi-bin/token"; public String doGet(String grantType, String appId, String secret){ String url = ACCESS_TOKEN_WEIXIN+"?grant_type="+grantType+ "&appid="+appId+"&secret="+secret; HttpURLConnection conn = null; InputStream is = null; InputStreamReader reader = null; BufferedReader br = null; String str = ""; try { URL weiUrl = new URL(url); conn = (HttpURLConnection)weiUrl.openConnection(); conn.setRequestProperty("connection", "Keep-Alive"); conn.connect(); is = conn.getInputStream(); reader = new InputStreamReader(is, "UTF⑻"); br = new BufferedReader(reader); String readLine = ""; while((readLine=br.readLine())!=null){ str+=readLine+" "; } } catch (Exception e) { e.printStackTrace(); }finally{ try{ if(br!=null){ br.close(); } if(conn!=null){ conn.disconnect(); } }catch(Exception e1){ e1.printStackTrace(); } } return str; }

我將InputStream流和InputStreamReader流都單獨定義援用是為了測試流關閉的問題,最后只關閉最外層流,由于外層流關閉的時候就將包裹的流1并關閉了。見下面的BufferedReader類的close方法:

public void close() throws IOException { synchronized (lock) { if (in == null) return; in.close(); in = null; cb = null; } }
其中,in就是包裹的流。


下面貼post方法的代碼,然后綜合比較1下,代碼:

public String doPost(String grantType, String appId, String secret){ HttpURLConnection conn = null; InputStream is = null; InputStreamReader reader = null; BufferedReader br = null; String str = ""; try { URL url = new URL(ACCESS_TOKEN_WEIXIN); conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true);//默許為false的,所以需要設置 conn.setUseCaches(false); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.connect(); OutputStream outStream = conn.getOutputStream(); DataOutputStream out = new DataOutputStream(outStream); String params = "grant_type="+grantType+ "&appid="+appId+"&secret="+secret; out.writeBytes(params); out.close(); is = conn.getInputStream(); reader = new InputStreamReader(is, "UTF⑻"); br = new BufferedReader(reader); String readLine = ""; while((readLine=br.readLine())!=null){ str+=readLine+" "; } } catch (Exception e) { e.printStackTrace(); }finally{ try{ if(br!=null){ br.close(); } if(conn!=null){ conn.disconnect(); } }catch(Exception e1){ e1.printStackTrace(); } } return str; }

兩相比較:

1.思路是1樣的:首先建立鏈接對象(URL)->由鏈接對象得到代理對象(HttpUrlConnection)->設置1些鏈接參數->啟動鏈接通道(conn.connect();)->進行輸出輸入操作

2.get方法參數是帶在鏈接上的,所以沒有單獨賦值操作,直接在啟動鏈接通道后得到輸入流便可得到返回值

3.post方法參數不帶在鏈接上,需要單獨賦值(賦值是使用輸出流來進行的),需要將輸出打開(conn.setDoOutput(true);)由于URLConnection默許輸出是false;而input是默許打開的,故不用重復設置。

4.讀取返回值方式1樣。


在研究進程中,對URLConnection怎樣得到的InputStream比較好奇,查看源碼為:

public InputStream getInputStream() throws IOException { throw new UnknownServiceException("protocol doesn't support input"); }

所以很迷惑,是jdk1.7 。等下來研究出來再補上來。

共勉!

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

緊跟上面,對jdk怎樣實現的getInputStream和getOutputStream和其他1些方法,經過研究,終究找到了。接下來釋疑:

需要注意到:

URL url = new URL(ACCESS_TOKEN_WEIXIN); conn = (HttpURLConnection)url.openConnection();


這里得到HttpUrlConnection的時候是使用了強轉得到的,故跟蹤到URL類的openConnection方法內->

public URLConnection openConnection() throws java.io.IOException { return handler.openConnection(this); }


這里的handler定義在URL類的上方->

transient URLStreamHandler handler;

然后去尋覓handler的賦值方法getURLStreamHandler,發現以下代碼->

if (handler == null) { String packagePrefixList = null; packagePrefixList = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction( protocolPathProp,"")); if (packagePrefixList != "") { packagePrefixList += "|"; } // REMIND: decide whether to allow the "null" class prefix // or not. packagePrefixList += JDK_PACKAGE_PREFIX; StringTokenizer packagePrefixIter = new StringTokenizer(packagePrefixList, "|"); while (handler == null && packagePrefixIter.hasMoreTokens()) { String packagePrefix = packagePrefixIter.nextToken().trim(); // do not try to instantiate the JDK gopher handler // unless the system property had been explicitly set if (protocol.equalsIgnoreCase(GOPHER) && packagePrefix.equals(JDK_PACKAGE_PREFIX) && !enableGopher) { continue; } try { String clsName = packagePrefix + "." + protocol + ".Handler"; Class cls = null; try { cls = Class.forName(clsName);

其中
JDK_PACKAGE_PREFIX
在類中定義的是:

private static final String JDK_PACKAGE_PREFIX = "sun.net.www.protocol";
再結合下面的
String clsName = packagePrefix + "." + protocol + ".Handler";
基本可以定位到handler類的實現類在sun.net.www.protocol.http.Handler。然后百度搜索以后找到源碼(jdk下沒有sun包的源碼)->

sun.net.www.protocol.http包的視圖  Handler.java的源碼 ->

protected java.net.URLConnection openConnection(URL u) throws IOException { return openConnection(u, (Proxy)null); } protected java.net.URLConnection openConnection(URL u, Proxy p) throws IOException { return new HttpURLConnection(u, p, this); }

可以看到返回值是HttpURLConnection,但是發現該類中并沒有引入java.net.HttpURLConnection類,故猜想在Handler的同包下有1個同名類,果然發現該類,源碼 ->

public class HttpURLConnection extends java.net.HttpURLConnection

這是關建行,該類繼承了java.net.HttpURLConnection類。所以返回該類可以由java.net.HttpURLConnection類的父類URLConnection接到,然后強轉成java.net.HttpURLConnection類。設計10分奇妙->

@Override public synchronized OutputStream getOutputStream() throws IOException { try { if (!doOutput) { throw new ProtocolException("cannot write to a URLConnection" + " if doOutput=false - call setDoOutput(true)"); } if (method.equals("GET")) { method = "POST"; // Backward compatibility } if (!"POST".equals(method) && !"PUT".equals(method) && "http".equals(url.getProtocol())) { throw new ProtocolException("HTTP method " + method + " doesn't support output"); } // if there's already an input stream open, throw an exception if (inputStream != null) { throw new ProtocolException("Cannot write output after reading input."); } if (!checkReuseConnection()) connect();
......

這就是getOutputStream的實現地方了,正好doOutput屬性的設置也在這里起到了作用。艾瑪,終究找到實現的地方了,其他方法原理1致了。

略微整理下:全部的類流轉進程就是:sun.net.www.protocol.http.HttpURLConnection轉化成java.net.URLConnection,然后強轉成java.net.HttpURLConnection。

暈乎~





生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: yellow字幕中文字幕最新 | 亚洲成a v人片在线观看 | 亚洲精品综合一区二区 | 日韩在线一区高清在线 | 91精品国产美女福到在线不卡 | 91中文字幕yellow字幕网 | 国产精品视频一区二区三区w | 亚洲欧美国产精品专区久久 | 国产主播福利一区二区 | 亚洲图片在线欧美专区图片 | 国产欧美在线观看不卡一 | 免费区欧美一级毛片精品 | 精品欧美一区二区三区在线 | 欧美黑人巨大 | 国产日韩精品欧美一区 | 日本护士做xxxxxx视频 | 特级黄色免费片 | 亚洲人成在线免费观看 | 国产午夜精品久久理论片小说 | 亚洲第五页 | 全免费a级毛片免费看不卡 全网毛片 | 亚洲永久免费 | 亚洲成a| 欧美另类xxx | 国产三级做爰高清视频a | 黑人性猛交xxxx乱大交一 | 精品国产日韩亚洲一区91 | 亚洲欧美精品中文字幕 | 欧美黑人xxxxww | 成人午夜视频在线播放 | 在线亚洲不卡 | 伊人网在线视频观看 | 亚洲页码| 欧美曰逼 | 亚洲综合国产一区在线 | 欧美日本一区二区三区道 | 男女自偷自拍视频免费观看篇 | 午夜dj在线观看免费视频 | 伦伦影院精品一区 | 欧美日韩午夜视频 | 国产在线不卡免费播放 |