# OkHttp使用教程
<p>Android系統提供了兩種HTTP通信類,HttpURLConnection和HttpClient。<br><a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">關于HttpURLConnection和HttpClient的選擇>>官方博客</a><br>盡管Google在大部分安卓版本中推薦使用HttpURLConnection,但是這個類相比HttpClient實在是太難用,太弱爆了。<br>OkHttp是一個相對成熟的解決方案,據說Android4.4的源碼中可以看到HttpURLConnection已經替換成OkHttp實現了。所以我們更有理由相信OkHttp的強大。</p><p>OkHttp 處理了很多網絡疑難雜癥:會從很多常用的連接問題中自動恢復。如果您的服務器配置了多個IP地址,當第一個IP連接失敗的時候,OkHttp會自動嘗試下一個IP。OkHttp還處理了代理服務器問題和SSL握手失敗問題。</p><p>使用 OkHttp 無需重寫您程序中的網絡代碼。OkHttp實現了幾乎和java.net.HttpURLConnection一樣的API。如果你用了 Apache HttpClient,則OkHttp也提供了一個對應的okhttp-apache 模塊。</p><p><br></p> <p class="runtimead">
</p> <blockquote><p>注:在國內使用OkHttp會因為這個問題導致部分酷派手機用戶無法聯網,所以對于大眾app來說,需要等待這個bug修復后再使用。或者嘗試使用OkHttp的老版本。<br>截止到目前,OkHttp一直沒有修復,并把修復計劃延遲到了OkHttp2.3中。不是所有設備都能重現,僅少量設備會出現這個問題。(如果問題這么明顯,OkHttp早就修復了)</p></blockquote><h1>入門</h1><h2>官方資料</h2><p><a href="http://square.github.io/okhttp/">官方介紹</a><br><a href="https://github.com/square/okhttp">github源碼</a></p><h2>使用范圍</h2><p>OkHttp支持Android 2.3及其以上版本。<br>對于Java, JDK1.7以上。</p><h2 id="jar">jar包準備</h2><p>官方介紹頁面有鏈接位置。這里把下載鏈接也寫在下面。<br><a href="http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.squareup.okhttp&a=okhttp&v=LATEST">OkHttp</a><br><a href="http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.squareup.okio&a=okio&v=LATEST">Okio</a></p><h2>基本使用</h2><h3 id="http-get">HTTP GET</h3><div><div id="highlighter_279020" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">String run(String url) throws IOException {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder().url(url).build();</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute(); </code><code class="js keyword">if</code> <code class="js plain">(response.isSuccessful()) { </code><code class="js keyword">return</code> <code class="js plain">response.body().string();</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">else</code> <code class="js plain">{ </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number8 index7 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><p>Request是OkHttp中訪問的請求,Builder是輔助類。Response即OkHttp中的響應。</p><h4 id="response">Response類:</h4><div><div id="highlighter_633330" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public boolean isSuccessful()</code></div><div class="line number2 index1 alt1"><code class="js plain">Returns </code><code class="js keyword">true</code> <code class="js keyword">if</code> <code class="js plain">the code is </code><code class="js keyword">in</code> <code class="js plain">[200..300),</code></div><div class="line number3 index2 alt2"><code class="js spaces"> </code><code class="js plain">which means the request was successfully received, understood, and accepted.</code></div></div></td></tr></tbody></table></div></div><h4 id="response.bodyresponsebody">response.body()返回ResponseBody類</h4><p>可以方便的獲取string</p><div><div id="highlighter_692410" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public final String string() throws IOException</code></div><div class="line number2 index1 alt1"><code class="js plain">Returns the response as a string decoded </code><code class="js keyword">with</code> <code class="js plain">the charset of the Content-Type header. If that header is either absent or lacks a charset,</code></div><div class="line number3 index2 alt2"><code class="js spaces"> </code><code class="js keyword">this</code> <code class="js plain">will attempt to decode the response body as UTF-8.Throws:</code></div><div class="line number4 index3 alt1"><code class="js plain">IOException</code></div></div></td></tr></tbody></table></div></div><p>當然也能獲取到流的形式:</p><div><div id="highlighter_617123" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public final InputStream byteStream()</code></div></div></td></tr></tbody></table></div></div><h3 id="http-post">HTTP POST</h3><h4 id="postjson">POST提交Json數據</h4><div><div id="highlighter_145107" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public static final MediaType JSON = MediaType.parse(</code><code class="js string">"application/json; charset=utf-8"</code><code class="js plain">);</code></div><div class="line number2 index1 alt1"><code class="js plain">OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number3 index2 alt2"><code class="js plain">String post(String url, String json) throws IOException {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">RequestBody body = RequestBody.create(JSON, json);</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.url(url)</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">.post(body)</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">f (response.isSuccessful()) {</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">response.body().string();</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">else</code> <code class="js plain">{</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number15 index14 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><p>使用Request的post方法來提交請求體RequestBody</p><h4 id="post">POST提交鍵值對</h4><p>很多時候我們會需要通過POST方式把鍵值對數據傳送到服務器。 OkHttp提供了很方便的方式來做這件事情。</p><div><div id="highlighter_283837" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"><code class="js plain">String post(String url, String json) throws IOException {</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">RequestBody formBody = </code><code class="js keyword">new</code> <code class="js plain">FormEncodingBuilder()</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">.add(</code><code class="js string">"platform"</code><code class="js plain">, </code><code class="js string">"android"</code><code class="js plain">)</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.add(</code><code class="js string">"name"</code><code class="js plain">, </code><code class="js string">"bug"</code><code class="js plain">)</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">.add(</code><code class="js string">"subject"</code><code class="js plain">, </code><code class="js string">"XXXXXXXXXXXXXXX"</code><code class="js plain">)</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number9 index8 alt2"> </div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">.url(url)</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">.post(body)</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number14 index13 alt1"> </div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(response.isSuccessful()) {</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">response.body().string();</code></div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">else</code> <code class="js plain">{</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number21 index20 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>總結</h2><p>通過上面的例子我們可以發現,OkHttp在很多時候使用都是很方便的,而且很多代碼也有重復,因此特地整理了下面的工具類。<br>注意:</p><ul class=" list-paddingleft-2"><li><p>OkHttp官方文檔并不建議我們創建多個OkHttpClient,因此全局使用一個。 如果有需要,可以使用clone方法,再進行自定義。這點在后面的高級教程里會提到。<br></p></li><li><p>enqueue為OkHttp提供的異步方法,入門教程中并沒有提到,后面的高級教程里會有解釋。</p></li></ul><div><div id="highlighter_544809" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div><div class="line number29 index28 alt2">29</div><div class="line number30 index29 alt1">30</div><div class="line number31 index30 alt2">31</div><div class="line number32 index31 alt1">32</div><div class="line number33 index32 alt2">33</div><div class="line number34 index33 alt1">34</div><div class="line number35 index34 alt2">35</div><div class="line number36 index35 alt1">36</div><div class="line number37 index36 alt2">37</div><div class="line number38 index37 alt1">38</div><div class="line number39 index38 alt2">39</div><div class="line number40 index39 alt1">40</div><div class="line number41 index40 alt2">41</div><div class="line number42 index41 alt1">42</div><div class="line number43 index42 alt2">43</div><div class="line number44 index43 alt1">44</div><div class="line number45 index44 alt2">45</div><div class="line number46 index45 alt1">46</div><div class="line number47 index46 alt2">47</div><div class="line number48 index47 alt1">48</div><div class="line number49 index48 alt2">49</div><div class="line number50 index49 alt1">50</div><div class="line number51 index50 alt2">51</div><div class="line number52 index51 alt1">52</div><div class="line number53 index52 alt2">53</div><div class="line number54 index53 alt1">54</div><div class="line number55 index54 alt2">55</div><div class="line number56 index55 alt1">56</div><div class="line number57 index56 alt2">57</div><div class="line number58 index57 alt1">58</div><div class="line number59 index58 alt2">59</div><div class="line number60 index59 alt1">60</div><div class="line number61 index60 alt2">61</div><div class="line number62 index61 alt1">62</div><div class="line number63 index62 alt2">63</div><div class="line number64 index63 alt1">64</div><div class="line number65 index64 alt2">65</div><div class="line number66 index65 alt1">66</div><div class="line number67 index66 alt2">67</div><div class="line number68 index67 alt1">68</div><div class="line number69 index68 alt2">69</div><div class="line number70 index69 alt1">70</div><div class="line number71 index70 alt2">71</div><div class="line number72 index71 alt1">72</div><div class="line number73 index72 alt2">73</div><div class="line number74 index73 alt1">74</div><div class="line number75 index74 alt2">75</div><div class="line number76 index75 alt1">76</div><div class="line number77 index76 alt2">77</div><div class="line number78 index77 alt1">78</div><div class="line number79 index78 alt2">79</div><div class="line number80 index79 alt1">80</div><div class="line number81 index80 alt2">81</div><div class="line number82 index81 alt1">82</div><div class="line number83 index82 alt2">83</div><div class="line number84 index83 alt1">84</div><div class="line number85 index84 alt2">85</div><div class="line number86 index85 alt1">86</div><div class="line number87 index86 alt2">87</div><div class="line number88 index87 alt1">88</div><div class="line number89 index88 alt2">89</div><div class="line number90 index89 alt1">90</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">import java.io.IOException;</code></div><div class="line number2 index1 alt1"><code class="js plain">import java.util.List;</code></div><div class="line number3 index2 alt2"><code class="js plain">import java.util.concurrent.TimeUnit;</code></div><div class="line number4 index3 alt1"><code class="js plain">import org.apache.http.client.utils.URLEncodedUtils;</code></div><div class="line number5 index4 alt2"><code class="js plain">import org.apache.http.message.BasicNameValuePair;</code></div><div class="line number6 index5 alt1"><code class="js plain">import cn.wiz.sdk.constant.WizConstant;</code></div><div class="line number7 index6 alt2"><code class="js plain">import com.squareup.okhttp.Callback;</code></div><div class="line number8 index7 alt1"><code class="js plain">import com.squareup.okhttp.OkHttpClient;</code></div><div class="line number9 index8 alt2"><code class="js plain">import com.squareup.okhttp.Request;</code></div><div class="line number10 index9 alt1"><code class="js plain">import com.squareup.okhttp.Response; </code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code> </div><div class="line number12 index11 alt1"><code class="js plain">public class OkHttpUtil {</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">private static final OkHttpClient mOkHttpClient = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">static{</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js comments">/**</code></div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js comments">* 該不會開啟異步線程。</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js comments">* @param request</code></div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js comments">* @return</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js comments">* @throws IOException</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js comments">*/</code></div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">public static Response execute(Request request) throws IOException{</code></div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">mOkHttpClient.newCall(request).execute();</code></div><div class="line number25 index24 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number26 index25 alt1"><code class="js spaces"> </code><code class="js comments">/**</code></div><div class="line number27 index26 alt2"><code class="js spaces"> </code><code class="js comments">* 開啟異步線程訪問網絡</code></div><div class="line number28 index27 alt1"><code class="js spaces"> </code><code class="js comments">* @param request</code></div><div class="line number29 index28 alt2"><code class="js spaces"> </code><code class="js comments">* @param responseCallback</code></div><div class="line number30 index29 alt1"><code class="js spaces"> </code><code class="js comments">*/</code></div><div class="line number31 index30 alt2"><code class="js spaces"> </code><code class="js plain">public static void enqueue(Request request, Callback responseCallback){</code></div><div class="line number32 index31 alt1"><code class="js spaces"> </code><code class="js plain">mOkHttpClient.newCall(request).enqueue(responseCallback);</code></div><div class="line number33 index32 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number34 index33 alt1"><code class="js spaces"> </code><code class="js comments">/**</code></div><div class="line number35 index34 alt2"><code class="js spaces"> </code><code class="js comments">* 開啟異步線程訪問網絡, 且不在意返回結果(實現空callback)</code></div><div class="line number36 index35 alt1"><code class="js spaces"> </code><code class="js comments">* @param request</code></div><div class="line number37 index36 alt2"><code class="js spaces"> </code><code class="js comments">*/</code></div><div class="line number38 index37 alt1"><code class="js spaces"> </code><code class="js plain">public static void enqueue(Request request){</code></div><div class="line number39 index38 alt2"><code class="js spaces"> </code><code class="js plain">mOkHttpClient.newCall(request).enqueue(</code><code class="js keyword">new</code> <code class="js plain">Callback() {</code></div><div class="line number40 index39 alt1"><code class="js spaces"> </code> </div><div class="line number41 index40 alt2"><code class="js spaces"> </code><code class="js plain">@Override</code></div><div class="line number42 index41 alt1"><code class="js spaces"> </code><code class="js plain">public void onResponse(Response arg0) throws IOException {</code></div><div class="line number43 index42 alt2"><code class="js spaces"> </code> </div><div class="line number44 index43 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number45 index44 alt2"><code class="js spaces"> </code> </div><div class="line number46 index45 alt1"><code class="js spaces"> </code><code class="js plain">@Override</code></div><div class="line number47 index46 alt2"><code class="js spaces"> </code><code class="js plain">public void onFailure(Request arg0, IOException arg1) {</code></div><div class="line number48 index47 alt1"><code class="js spaces"> </code> </div><div class="line number49 index48 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number50 index49 alt1"><code class="js spaces"> </code><code class="js plain">});</code></div><div class="line number51 index50 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number52 index51 alt1"><code class="js spaces"> </code><code class="js plain">public static String getStringFromServer(String url) throws IOException{</code></div><div class="line number53 index52 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder().url(url).build();</code></div><div class="line number54 index53 alt1"><code class="js spaces"> </code><code class="js plain">Response response = execute(request);</code></div><div class="line number55 index54 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(response.isSuccessful()) {</code></div><div class="line number56 index55 alt1"><code class="js spaces"> </code><code class="js plain">String responseUrl = response.body().string();</code></div><div class="line number57 index56 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">responseUrl;</code></div><div class="line number58 index57 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">else</code> <code class="js plain">{</code></div><div class="line number59 index58 alt2"><code class="js spaces"> </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number60 index59 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number61 index60 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number62 index61 alt1"><code class="js spaces"> </code><code class="js plain">private static final String CHARSET_NAME = </code><code class="js string">"UTF-8"</code><code class="js plain">;</code></div><div class="line number63 index62 alt2"><code class="js spaces"> </code><code class="js comments">/**</code></div><div class="line number64 index63 alt1"><code class="js spaces"> </code><code class="js comments">* 這里使用了HttpClinet的API。只是為了方便</code></div><div class="line number65 index64 alt2"><code class="js spaces"> </code><code class="js comments">* @param params</code></div><div class="line number66 index65 alt1"><code class="js spaces"> </code><code class="js comments">* @return</code></div><div class="line number67 index66 alt2"><code class="js spaces"> </code><code class="js comments">*/</code></div><div class="line number68 index67 alt1"><code class="js spaces"> </code><code class="js plain">public static String formatParams(List<BasicNameValuePair> params){</code></div><div class="line number69 index68 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">URLEncodedUtils.format(params, CHARSET_NAME);</code></div><div class="line number70 index69 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number71 index70 alt2"><code class="js spaces"> </code><code class="js comments">/**</code></div><div class="line number72 index71 alt1"><code class="js spaces"> </code><code class="js comments">* 為HttpGet 的 url 方便的添加多個name value 參數。</code></div><div class="line number73 index72 alt2"><code class="js spaces"> </code><code class="js comments">* @param url</code></div><div class="line number74 index73 alt1"><code class="js spaces"> </code><code class="js comments">* @param params</code></div><div class="line number75 index74 alt2"><code class="js spaces"> </code><code class="js comments">* @return</code></div><div class="line number76 index75 alt1"><code class="js spaces"> </code><code class="js comments">*/</code></div><div class="line number77 index76 alt2"><code class="js spaces"> </code><code class="js plain">public static String attachHttpGetParams(String url, List<BasicNameValuePair> params){</code></div><div class="line number78 index77 alt1"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">url + </code><code class="js string">"?"</code> <code class="js plain">+ formatParams(params);</code></div><div class="line number79 index78 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number80 index79 alt1"><code class="js spaces"> </code><code class="js comments">/**</code></div><div class="line number81 index80 alt2"><code class="js spaces"> </code><code class="js comments">* 為HttpGet 的 url 方便的添加1個name value 參數。</code></div><div class="line number82 index81 alt1"><code class="js spaces"> </code><code class="js comments">* @param url</code></div><div class="line number83 index82 alt2"><code class="js spaces"> </code><code class="js comments">* @param name</code></div><div class="line number84 index83 alt1"><code class="js spaces"> </code><code class="js comments">* @param value</code></div><div class="line number85 index84 alt2"><code class="js spaces"> </code><code class="js comments">* @return</code></div><div class="line number86 index85 alt1"><code class="js spaces"> </code><code class="js comments">*/</code></div><div class="line number87 index86 alt2"><code class="js spaces"> </code><code class="js plain">public static String attachHttpGetParam(String url, String name, String value){</code></div><div class="line number88 index87 alt1"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">url + </code><code class="js string">"?"</code> <code class="js plain">+ name + </code><code class="js string">"="</code> <code class="js plain">+ value;</code></div><div class="line number89 index88 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number90 index89 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h1>高級</h1><p>高級屬性其實用的不多,這里主要是對OkHttp github官方教程進行了翻譯。<br></p><h2>同步get</h2><p>下載一個文件,打印他的響應頭,以string形式打印響應體。<br>響應體的 <code>string()</code> 方法對于小文檔來說十分方便、高效。但是如果響應體太大(超過1MB),應避免適應 <code>string()</code>方法 ,因為他會將把整個文檔加載到內存中。<br>對于超過1MB的響應body,應使用流的方式來處理body。<a href="http://www.cnblogs.com/ct2011/p/3997368.html"></a></p><div><div id="highlighter_613263" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://publicobject.com/helloworld.txt">http://publicobject.com/helloworld.txt</a>"</code><code class="js plain">)</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number7 index6 alt2"> </div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number10 index9 alt1"> </div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">Headers responseHeaders = response.headers();</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js keyword">for</code> <code class="js plain">(int i = 0; i < responseHeaders.size(); i++) {</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(responseHeaders.name(i) + </code><code class="js string">": "</code> <code class="js plain">+ responseHeaders.value(i));</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number15 index14 alt2"> </div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number17 index16 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><p><a href="http://www.cnblogs.com/ct2011/p/3997368.html"></a></p><h2>異步get</h2><p>在一個工作線程中下載文件,當響應可讀時回調Callback接口。讀取響應時會阻塞當前線程。OkHttp現階段不提供異步api來接收響應體。</p><div><div id="highlighter_828037" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://publicobject.com/helloworld.txt">http://publicobject.com/helloworld.txt</a>"</code><code class="js plain">)</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number7 index6 alt2"> </div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">client.newCall(request).enqueue(</code><code class="js keyword">new</code> <code class="js plain">Callback() {</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">@Override public void onFailure(Request request, Throwable throwable) {</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">throwable.printStackTrace();</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number12 index11 alt1"> </div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">@Override public void onResponse(Response response) throws IOException {</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number15 index14 alt2"> </div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">Headers responseHeaders = response.headers();</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js keyword">for</code> <code class="js plain">(int i = 0; i < responseHeaders.size(); i++) {</code></div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(responseHeaders.name(i) + </code><code class="js string">": "</code> <code class="js plain">+ responseHeaders.value(i));</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number20 index19 alt1"> </div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">});</code></div><div class="line number24 index23 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>提取響應頭</h2><p>典型的HTTP頭 像是一個 <code>Map<String, String></code> :每個字段都有一個或沒有值。但是一些頭允許多個值,像Guava的<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html">Multimap</a>。例如:HTTP響應里面提供的<code>Vary</code>響應頭,就是多值的。OkHttp的api試圖讓這些情況都適用。<br>當寫請求頭的時候,使用<code>header(name, value)</code>可以設置唯一的name、value。如果已經有值,舊的將被移除,然后添加新的。使用<code>addHeader(name, value)</code>可以添加多值(添加,不移除已有的)。<br>當讀取響應頭時,使用<code>header(name)</code>返回最后出現的name、value。通常情況這也是唯一的name、value。如果沒有值,那么<code>header(name)</code>將返回null。如果想讀取字段對應的所有值,使用<code>headers(name)</code>會返回一個list。<br>為了獲取所有的Header,Headers類支持按index訪問。</p><div><div id="highlighter_716956" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://api.github.com/repos/square/okhttp/issues">https://api.github.com/repos/square/okhttp/issues</a>"</code><code class="js plain">)</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.header(</code><code class="js string">"User-Agent"</code><code class="js plain">, </code><code class="js string">"OkHttp Headers.java"</code><code class="js plain">)</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">.addHeader(</code><code class="js string">"Accept"</code><code class="js plain">, </code><code class="js string">"application/json; q=0.5"</code><code class="js plain">)</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">.addHeader(</code><code class="js string">"Accept"</code><code class="js plain">, </code><code class="js string">"application/vnd.github.v3+json"</code><code class="js plain">)</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number10 index9 alt1"> </div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number13 index12 alt2"> </div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Server: "</code> <code class="js plain">+ response.header(</code><code class="js string">"Server"</code><code class="js plain">));</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Date: "</code> <code class="js plain">+ response.header(</code><code class="js string">"Date"</code><code class="js plain">));</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Vary: "</code> <code class="js plain">+ response.headers(</code><code class="js string">"Vary"</code><code class="js plain">));</code></div><div class="line number17 index16 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>Post方式提交String</h2><p>使用HTTP POST提交請求到服務。這個例子提交了一個markdown文檔到web服務,以HTML方式渲染markdown。因為整個請求體都在內存中,因此避免使用此api提交大文檔(大于1MB)。</p><div><div id="highlighter_280488" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public static final MediaType MEDIA_TYPE_MARKDOWN</code></div><div class="line number2 index1 alt1"><code class="js spaces"> </code><code class="js plain">= MediaType.parse(</code><code class="js string">"text/x-markdown; charset=utf-8"</code><code class="js plain">);</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number5 index4 alt2"> </div><div class="line number6 index5 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">String postBody = </code><code class="js string">""</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">+ </code><code class="js string">"Releases\n"</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">+ </code><code class="js string">"--------\n"</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">+ </code><code class="js string">"\n"</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">+ </code><code class="js string">" * _1.0_ May 6, 2013\n"</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">+ </code><code class="js string">" * _1.1_ June 15, 2013\n"</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">+ </code><code class="js string">" * _1.2_ August 11, 2013\n"</code><code class="js plain">;</code></div><div class="line number14 index13 alt1"> </div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://api.github.com/markdown/raw">https://api.github.com/markdown/raw</a>"</code><code class="js plain">)</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js plain">.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))</code></div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number19 index18 alt2"> </div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number22 index21 alt1"> </div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number24 index23 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>Post方式提交流</h2><p>以流的方式POST提交請求體。請求體的內容由流寫入產生。這個例子是流直接寫入<a href="https://github.com/square/okio">Okio</a>的BufferedSink。你的程序可能會使用<code>OutputStream</code>,你可以使用<code>BufferedSink.outputStream()</code>來獲取。</p><div><div id="highlighter_546966" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div><div class="line number29 index28 alt2">29</div><div class="line number30 index29 alt1">30</div><div class="line number31 index30 alt2">31</div><div class="line number32 index31 alt1">32</div><div class="line number33 index32 alt2">33</div><div class="line number34 index33 alt1">34</div><div class="line number35 index34 alt2">35</div><div class="line number36 index35 alt1">36</div><div class="line number37 index36 alt2">37</div><div class="line number38 index37 alt1">38</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public static final MediaType MEDIA_TYPE_MARKDOWN</code></div><div class="line number2 index1 alt1"><code class="js spaces"> </code><code class="js plain">= MediaType.parse(</code><code class="js string">"text/x-markdown; charset=utf-8"</code><code class="js plain">);</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number5 index4 alt2"> </div><div class="line number6 index5 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">RequestBody requestBody = </code><code class="js keyword">new</code> <code class="js plain">RequestBody() {</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">@Override public MediaType contentType() {</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">MEDIA_TYPE_MARKDOWN;</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number11 index10 alt2"> </div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">@Override public void writeTo(BufferedSink sink) throws IOException {</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">sink.writeUtf8(</code><code class="js string">"Numbers\n"</code><code class="js plain">);</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">sink.writeUtf8(</code><code class="js string">"-------\n"</code><code class="js plain">);</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js keyword">for</code> <code class="js plain">(int i = 2; i <= 997; i++) {</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">sink.writeUtf8(String.format(</code><code class="js string">" * %s = %s\n"</code><code class="js plain">, i, factor(i)));</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number19 index18 alt2"> </div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">private String factor(int n) {</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js keyword">for</code> <code class="js plain">(int i = 2; i < n; i++) {</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js plain">int x = n / i;</code></div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(x * i == n) </code><code class="js keyword">return</code> <code class="js plain">factor(x) + </code><code class="js string">" × "</code> <code class="js plain">+ i;</code></div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number25 index24 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">Integer.toString(n);</code></div><div class="line number26 index25 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number27 index26 alt2"><code class="js spaces"> </code><code class="js plain">};</code></div><div class="line number28 index27 alt1"> </div><div class="line number29 index28 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number30 index29 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://api.github.com/markdown/raw">https://api.github.com/markdown/raw</a>"</code><code class="js plain">)</code></div><div class="line number31 index30 alt2"><code class="js spaces"> </code><code class="js plain">.post(requestBody)</code></div><div class="line number32 index31 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number33 index32 alt2"> </div><div class="line number34 index33 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number35 index34 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number36 index35 alt1"> </div><div class="line number37 index36 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number38 index37 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>Post方式提交文件</h2><p>以文件作為請求體是十分簡單的。</p><div><div id="highlighter_632828" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public static final MediaType MEDIA_TYPE_MARKDOWN</code></div><div class="line number2 index1 alt1"><code class="js spaces"> </code><code class="js plain">= MediaType.parse(</code><code class="js string">"text/x-markdown; charset=utf-8"</code><code class="js plain">);</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number5 index4 alt2"> </div><div class="line number6 index5 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">File file = </code><code class="js keyword">new</code> <code class="js plain">File(</code><code class="js string">"README.md"</code><code class="js plain">);</code></div><div class="line number8 index7 alt1"> </div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://api.github.com/markdown/raw">https://api.github.com/markdown/raw</a>"</code><code class="js plain">)</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number13 index12 alt2"> </div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number16 index15 alt1"> </div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number18 index17 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>Post方式提交表單</h2><p>使用<code>FormEncodingBuilder</code>來構建和HTML<code><form></code>標簽相同效果的請求體。鍵值對將使用一種HTML兼容形式的URL編碼來進行編碼。</p><div><div id="highlighter_260504" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">RequestBody formBody = </code><code class="js keyword">new</code> <code class="js plain">FormEncodingBuilder()</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">.add(</code><code class="js string">"search"</code><code class="js plain">, </code><code class="js string">"Jurassic Park"</code><code class="js plain">)</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://en.wikipedia.org/w/index.php">https://en.wikipedia.org/w/index.php</a>"</code><code class="js plain">)</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">.post(formBody)</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number11 index10 alt2"> </div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number14 index13 alt1"> </div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number16 index15 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>Post方式提交分塊請求</h2><p><code>MultipartBuilder</code>可以構建復雜的請求體,與HTML文件上傳形式兼容。多塊請求體中每塊請求都是一個請求體,可以定義自己的請求頭。這些請求頭可以用來描述這塊請求,例如他的<code>Content-Disposition</code>。如果<code>Content-Length</code>和<code>Content-Type</code>可用的話,他們會被自動添加到請求頭中。</p><div><div id="highlighter_91012" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private static final String IMGUR_CLIENT_ID = </code><code class="js string">"..."</code><code class="js plain">;</code></div><div class="line number2 index1 alt1"><code class="js plain">private static final MediaType MEDIA_TYPE_PNG = MediaType.parse(</code><code class="js string">"image/png"</code><code class="js plain">);</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number5 index4 alt2"> </div><div class="line number6 index5 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js comments">// Use the imgur image upload API as documented at <a href="https://api.imgur.com/endpoints/image">https://api.imgur.com/endpoints/image</a></code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">RequestBody requestBody = </code><code class="js keyword">new</code> <code class="js plain">MultipartBuilder()</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">.type(MultipartBuilder.FORM)</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">.addPart(</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">Headers.of(</code><code class="js string">"Content-Disposition"</code><code class="js plain">, </code><code class="js string">"form-data; name=\"title\""</code><code class="js plain">),</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">RequestBody.create(</code><code class="js keyword">null</code><code class="js plain">, </code><code class="js string">"Square Logo"</code><code class="js plain">))</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">.addPart(</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">Headers.of(</code><code class="js string">"Content-Disposition"</code><code class="js plain">, </code><code class="js string">"form-data; name=\"image\""</code><code class="js plain">),</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">RequestBody.create(MEDIA_TYPE_PNG, </code><code class="js keyword">new</code> <code class="js plain">File(</code><code class="js string">"website/static/logo-square.png"</code><code class="js plain">)))</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number17 index16 alt2"> </div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">.header(</code><code class="js string">"Authorization"</code><code class="js plain">, </code><code class="js string">"Client-ID "</code> <code class="js plain">+ IMGUR_CLIENT_ID)</code></div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://api.imgur.com/3/image">https://api.imgur.com/3/image</a>"</code><code class="js plain">)</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js plain">.post(requestBody)</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number23 index22 alt2"> </div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number25 index24 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number26 index25 alt1"> </div><div class="line number27 index26 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number28 index27 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>使用Gson來解析JSON響應</h2><p>Gson是一個在JSON和Java對象之間轉換非常方便的api。這里我們用Gson來解析Github API的JSON響應。<br>注意:<code>ResponseBody.charStream()</code>使用響應頭<code>Content-Type</code>指定的字符集來解析響應體。默認是UTF-8。</p><div><div id="highlighter_680583" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"><code class="js plain">private final Gson gson = </code><code class="js keyword">new</code> <code class="js plain">Gson();</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="https://api.github.com/gists/c2a7c39532239ff261be">https://api.github.com/gists/c2a7c39532239ff261be</a>"</code><code class="js plain">)</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number10 index9 alt1"> </div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">Gist gist = gson.fromJson(response.body().charStream(), Gist.class);</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js keyword">for</code> <code class="js plain">(Map.Entry<String, GistFile> entry : gist.files.entrySet()) {</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(entry.getKey());</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(entry.getValue().content);</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number16 index15 alt1"><code class="js plain">}</code></div><div class="line number17 index16 alt2"> </div><div class="line number18 index17 alt1"><code class="js plain">static class Gist {</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">Map<String, GistFile> files;</code></div><div class="line number20 index19 alt1"><code class="js plain">}</code></div><div class="line number21 index20 alt2"> </div><div class="line number22 index21 alt1"><code class="js plain">static class GistFile {</code></div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">String content;</code></div><div class="line number24 index23 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>響應緩存</h2><p>為了緩存響應,你需要一個你可以讀寫的緩存目錄,和緩存大小的限制。這個緩存目錄應該是私有的,不信任的程序應不能讀取緩存內容。<br>一個緩存目錄同時擁有多個緩存訪問是錯誤的。大多數程序只需要調用一次<code>new OkHttp()</code>,在第一次調用時配置好緩存,然后其他地方只需要調用這個實例就可以了。否則兩個緩存示例互相干擾,破壞響應緩存,而且有可能會導致程序崩潰。<br>響應緩存使用HTTP頭作為配置。你可以在請求頭中添加<code>Cache-Control: max-stale=3600</code> ,OkHttp緩存會支持。你的服務通過響應頭確定響應緩存多長時間,例如使用<code>Cache-Control: max-age=9600</code>。</p><div><div id="highlighter_443848" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div><div class="line number29 index28 alt2">29</div><div class="line number30 index29 alt1">30</div><div class="line number31 index30 alt2">31</div><div class="line number32 index31 alt1">32</div><div class="line number33 index32 alt2">33</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client;</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public CacheResponse(File cacheDirectory) throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">int cacheSize = 10 * 1024 * 1024; </code><code class="js comments">// 10 MiB</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">Cache cache = </code><code class="js keyword">new</code> <code class="js plain">Cache(cacheDirectory, cacheSize);</code></div><div class="line number6 index5 alt1"> </div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">client.setCache(cache);</code></div><div class="line number9 index8 alt2"><code class="js plain">}</code></div><div class="line number10 index9 alt1"> </div><div class="line number11 index10 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://publicobject.com/helloworld.txt">http://publicobject.com/helloworld.txt</a>"</code><code class="js plain">)</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number15 index14 alt2"> </div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">Response response1 = client.newCall(request).execute();</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response1.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response1);</code></div><div class="line number18 index17 alt1"> </div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">String response1Body = response1.body().string();</code></div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 1 response: "</code> <code class="js plain">+ response1);</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 1 cache response: "</code> <code class="js plain">+ response1.cacheResponse());</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 1 network response: "</code> <code class="js plain">+ response1.networkResponse());</code></div><div class="line number23 index22 alt2"> </div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js plain">Response response2 = client.newCall(request).execute();</code></div><div class="line number25 index24 alt2"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response2.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response2);</code></div><div class="line number26 index25 alt1"> </div><div class="line number27 index26 alt2"><code class="js spaces"> </code><code class="js plain">String response2Body = response2.body().string();</code></div><div class="line number28 index27 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 2 response: "</code> <code class="js plain">+ response2);</code></div><div class="line number29 index28 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 2 cache response: "</code> <code class="js plain">+ response2.cacheResponse());</code></div><div class="line number30 index29 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 2 network response: "</code> <code class="js plain">+ response2.networkResponse());</code></div><div class="line number31 index30 alt2"> </div><div class="line number32 index31 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 2 equals Response 1? "</code> <code class="js plain">+ response1Body.equals(response2Body));</code></div><div class="line number33 index32 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>擴展</h2><p>在這一節還提到了下面一句:<br>There are cache headers to force a cached response,
force a network response, or force the network response to be validated
with a conditional GET.</p><p>我不是很懂cache,平時用到的也不多,所以把Google在Android Developers一段相關的解析放到這里吧。</p><h3 id="force-a-network-response">Force a Network Response</h3><p>In some situations, such as after a user clicks a 'refresh' button,
it may be necessary to skip the cache, and fetch data directly from the
server. To force a full refresh, add the no-cache directive:</p><pre class="java">connection.addRequestProperty("Cache-Control", "no-cache");</pre><p>If it is only necessary to force a cached response to be validated by the server, use the more efficient max-age=0 instead:</p><pre class="java">connection.addRequestProperty("Cache-Control", "max-age=0");</pre><h3 id="force-a-cache-response">Force a Cache Response</h3><p>Sometimes you'll want to show resources if they are available
immediately, but not otherwise. This can be used so your application can
show something while waiting for the latest data to be downloaded. To
restrict a request to locally-cached resources, add the only-if-cached
directive:</p><div><div id="highlighter_710257" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js keyword">try</code> <code class="js plain">{</code></div><div class="line number2 index1 alt1"><code class="js spaces"> </code><code class="js plain">connection.addRequestProperty(</code><code class="js string">"Cache-Control"</code><code class="js plain">, </code><code class="js string">"only-if-cached"</code><code class="js plain">);</code></div><div class="line number3 index2 alt2"><code class="js spaces"> </code><code class="js plain">InputStream cached = connection.getInputStream();</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js comments">// the resource was cached! show it</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js keyword">catch</code> <code class="js plain">(FileNotFoundException e) {</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js comments">// the resource was not cached</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number8 index7 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><p>This technique works even better in situations where a stale response is
better than no response. To permit stale cached responses, use the
max-stale directive with the maximum staleness in seconds:</p><div><div id="highlighter_392790" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">int maxStale = 60 * 60 * 24 * 28; </code><code class="js comments">// tolerate 4-weeks staleconnection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);</code></div></div></td></tr></tbody></table></div></div><p>以上信息來自:<a href="http://developer.android.com/reference/android/net/http/HttpResponseCache.html">HttpResponseCache - Android SDK | Android Developers</a></p><h2>取消一個Call</h2><p>使用<code>Call.cancel()</code>可以立即停止掉一個正在執行的call。如果一個線程正在寫請求或者讀響應,將會引發<code>IOException</code>。當call沒有必要的時候,使用這個api可以節約網絡資源。例如當用戶離開一個應用時。不管同步還是異步的call都可以取消。<br>你可以通過tags來同時取消多個請求。當你構建一請求時,使用<code>RequestBuilder.tag(tag)</code>來分配一個標簽。之后你就可以用<code>OkHttpClient.cancel(tag)</code>來取消所有帶有這個tag的call。</p><div><div id="highlighter_586672" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div><div class="line number29 index28 alt2">29</div><div class="line number30 index29 alt1">30</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);</code></div><div class="line number2 index1 alt1"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number3 index2 alt2"> </div><div class="line number4 index3 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://httpbin.org/delay/2">http://httpbin.org/delay/2</a>"</code><code class="js plain">) // This URL is served </code><code class="js keyword">with</code> <code class="js plain">a 2 second delay.</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number8 index7 alt1"> </div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">final long startNanos = System.nanoTime();</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">final Call call = client.newCall(request);</code></div><div class="line number11 index10 alt2"> </div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js comments">// Schedule a job to cancel the call in 1 second.</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">executor.schedule(</code><code class="js keyword">new</code> <code class="js plain">Runnable() {</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">@Override public void run() {</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">System.out.printf(</code><code class="js string">"%.2f Canceling call.%n"</code><code class="js plain">, (System.nanoTime() - startNanos) / 1e9f);</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">call.cancel();</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js plain">System.out.printf(</code><code class="js string">"%.2f Canceled call.%n"</code><code class="js plain">, (System.nanoTime() - startNanos) / 1e9f);</code></div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">}, 1, TimeUnit.SECONDS);</code></div><div class="line number20 index19 alt1"> </div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js keyword">try</code> <code class="js plain">{</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js plain">System.out.printf(</code><code class="js string">"%.2f Executing call.%n"</code><code class="js plain">, (System.nanoTime() - startNanos) / 1e9f);</code></div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">Response response = call.execute();</code></div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js plain">System.out.printf(</code><code class="js string">"%.2f Call was expected to fail, but completed: %s%n"</code><code class="js plain">,</code></div><div class="line number25 index24 alt2"><code class="js spaces"> </code><code class="js plain">(System.nanoTime() - startNanos) / 1e9f, response);</code></div><div class="line number26 index25 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">catch</code> <code class="js plain">(IOException e) {</code></div><div class="line number27 index26 alt2"><code class="js spaces"> </code><code class="js plain">System.out.printf(</code><code class="js string">"%.2f Call failed as expected: %s%n"</code><code class="js plain">,</code></div><div class="line number28 index27 alt1"><code class="js spaces"> </code><code class="js plain">(System.nanoTime() - startNanos) / 1e9f, e);</code></div><div class="line number29 index28 alt2"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number30 index29 alt1"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>超時</h2><p>沒有響應時使用超時結束call。沒有響應的原因可能是客戶點鏈接問題、服務器可用性問題或者這之間的其他東西。OkHttp支持連接,讀取和寫入超時。</p><div><div id="highlighter_302060" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client;</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public ConfigureTimeouts() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">client.setConnectTimeout(10, TimeUnit.SECONDS);</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">client.setWriteTimeout(10, TimeUnit.SECONDS);</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">client.setReadTimeout(30, TimeUnit.SECONDS);</code></div><div class="line number8 index7 alt1"><code class="js plain">}</code></div><div class="line number9 index8 alt2"> </div><div class="line number10 index9 alt1"><code class="js plain">public void run() throws Exception {</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://httpbin.org/delay/2">http://httpbin.org/delay/2</a>"</code><code class="js plain">) // This URL is served </code><code class="js keyword">with</code> <code class="js plain">a 2 second delay.</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number14 index13 alt1"> </div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response completed: "</code> <code class="js plain">+ response);</code></div><div class="line number17 index16 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>每個call的配置</h2><p>使用<code>OkHttpClient</code>,所有的HTTP Client配置包括代理設置、超時設置、緩存設置。當你需要為單個call改變配置的時候,clone 一個 <code>OkHttpClient</code>。這個api將會返回一個淺拷貝(shallow copy),你可以用來單獨自定義。下面的例子中,我們讓一個請求是500ms的超時、另一個是3000ms的超時。</p><div><div id="highlighter_384340" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://httpbin.org/delay/1">http://httpbin.org/delay/1</a>"</code><code class="js plain">) // This URL is served </code><code class="js keyword">with</code> <code class="js plain">a 1 second delay.</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number7 index6 alt2"> </div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js keyword">try</code> <code class="js plain">{</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.clone() </code><code class="js comments">// Clone to make a customized OkHttp for this request.</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">.setReadTimeout(500, TimeUnit.MILLISECONDS)</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">.newCall(request)</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">.execute();</code></div><div class="line number13 index12 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 1 succeeded: "</code> <code class="js plain">+ response);</code></div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">catch</code> <code class="js plain">(IOException e) {</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 1 failed: "</code> <code class="js plain">+ e);</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number17 index16 alt2"> </div><div class="line number18 index17 alt1"><code class="js spaces"> </code><code class="js keyword">try</code> <code class="js plain">{</code></div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.clone() </code><code class="js comments">// Clone to make a customized OkHttp for this request.</code></div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">.setReadTimeout(3000, TimeUnit.MILLISECONDS)</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js plain">.newCall(request)</code></div><div class="line number22 index21 alt1"><code class="js spaces"> </code><code class="js plain">.execute();</code></div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 2 succeeded: "</code> <code class="js plain">+ response);</code></div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js plain">} </code><code class="js keyword">catch</code> <code class="js plain">(IOException e) {</code></div><div class="line number25 index24 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Response 2 failed: "</code> <code class="js plain">+ e);</code></div><div class="line number26 index25 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number27 index26 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><h2>處理驗證</h2><p>這部分和HTTP AUTH有關。<br>相關資料:<a href="http://blog.csdn.net/wwwsq/article/details/7255062">HTTP AUTH 那些事 - 王紹全的博客 - 博客頻道 - CSDN.NET</a></p><p>OkHttp會自動重試未驗證的請求。當響應是<code>401 Not Authorized</code>時,<code>Authenticator</code>會被要求提供證書。Authenticator的實現中需要建立一個新的包含證書的請求。如果沒有證書可用,返回null來跳過嘗試。</p><div><div id="highlighter_968965" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">public List<Challenge> challenges()</code></div><div class="line number2 index1 alt1"><code class="js plain">Returns the authorization challenges appropriate </code><code class="js keyword">for</code> <code class="js keyword">this</code> <code class="js plain">response's code. </code></div><div class="line number3 index2 alt2"><code class="js plain">If the response code is 401 unauthorized, </code></div><div class="line number4 index3 alt1"><code class="js keyword">this</code> <code class="js plain">returns the </code><code class="js string">"WWW-Authenticate"</code> <code class="js plain">challenges.</code></div><div class="line number5 index4 alt2"><code class="js plain">If the response code is 407 proxy unauthorized, </code><code class="js keyword">this</code> <code class="js plain">returns the </code><code class="js string">"Proxy-Authenticate"</code> <code class="js plain">challenges.</code></div><div class="line number6 index5 alt1"><code class="js plain">Otherwise </code><code class="js keyword">this</code> <code class="js plain">returns an empty list of challenges.</code></div></div></td></tr></tbody></table></div></div><p>當需要實現一個<code>Basic</code> challenge, 使用<code>Credentials.basic(username, password)</code>來編碼請求頭。</p><div><div id="highlighter_969377" class="syntaxhighlighter js"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">private final OkHttpClient client = </code><code class="js keyword">new</code> <code class="js plain">OkHttpClient();</code></div><div class="line number2 index1 alt1"> </div><div class="line number3 index2 alt2"><code class="js plain">public void run() throws Exception {</code></div><div class="line number4 index3 alt1"><code class="js spaces"> </code><code class="js plain">client.setAuthenticator(</code><code class="js keyword">new</code> <code class="js plain">Authenticator() {</code></div><div class="line number5 index4 alt2"><code class="js spaces"> </code><code class="js plain">@Override public Request authenticate(Proxy proxy, Response response) {</code></div><div class="line number6 index5 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Authenticating for response: "</code> <code class="js plain">+ response);</code></div><div class="line number7 index6 alt2"><code class="js spaces"> </code><code class="js plain">System.out.println(</code><code class="js string">"Challenges: "</code> <code class="js plain">+ response.challenges());</code></div><div class="line number8 index7 alt1"><code class="js spaces"> </code><code class="js plain">String credential = Credentials.basic(</code><code class="js string">"jesse"</code><code class="js plain">, </code><code class="js string">"password1"</code><code class="js plain">);</code></div><div class="line number9 index8 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js plain">response.request().newBuilder()</code></div><div class="line number10 index9 alt1"><code class="js spaces"> </code><code class="js plain">.header(</code><code class="js string">"Authorization"</code><code class="js plain">, credential)</code></div><div class="line number11 index10 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number12 index11 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number13 index12 alt2"> </div><div class="line number14 index13 alt1"><code class="js spaces"> </code><code class="js plain">@Override public Request authenticateProxy(Proxy proxy, Response response) {</code></div><div class="line number15 index14 alt2"><code class="js spaces"> </code><code class="js keyword">return</code> <code class="js keyword">null</code><code class="js plain">; </code><code class="js comments">// Null indicates no attempt to authenticate.</code></div><div class="line number16 index15 alt1"><code class="js spaces"> </code><code class="js plain">}</code></div><div class="line number17 index16 alt2"><code class="js spaces"> </code><code class="js plain">});</code></div><div class="line number18 index17 alt1"> </div><div class="line number19 index18 alt2"><code class="js spaces"> </code><code class="js plain">Request request = </code><code class="js keyword">new</code> <code class="js plain">Request.Builder()</code></div><div class="line number20 index19 alt1"><code class="js spaces"> </code><code class="js plain">.url(</code><code class="js string">"<a href="http://publicobject.com/secrets/hellosecret.txt">http://publicobject.com/secrets/hellosecret.txt</a>"</code><code class="js plain">)</code></div><div class="line number21 index20 alt2"><code class="js spaces"> </code><code class="js plain">.build();</code></div><div class="line number22 index21 alt1"> </div><div class="line number23 index22 alt2"><code class="js spaces"> </code><code class="js plain">Response response = client.newCall(request).execute();</code></div><div class="line number24 index23 alt1"><code class="js spaces"> </code><code class="js keyword">if</code> <code class="js plain">(!response.isSuccessful()) </code><code class="js keyword">throw</code> <code class="js keyword">new</code> <code class="js plain">IOException(</code><code class="js string">"Unexpected code "</code> <code class="js plain">+ response);</code></div><div class="line number25 index24 alt2"> </div><div class="line number26 index25 alt1"><code class="js spaces"> </code><code class="js plain">System.out.println(response.body().string());</code></div><div class="line number27 index26 alt2"><code class="js plain">}</code></div></div></td></tr></tbody></table></div></div><p><br></p><p>轉自 <a textvalue="OkHttp使用介紹" target="_self" href="http://www.cnblogs.com/ct2011/p/4001708.html">OkHttp使用介紹</a> 同時整合了 <a textvalue="OkHttp使用進階" target="_self" href="http://www.cnblogs.com/ct2011/p/3997368.html">OkHttp使用進階</a> 這篇文章以及其中的評論。</p>
- Introduction
- 爬蟲相關技能介紹
- 爬蟲簡單介紹
- 爬蟲涉及到的知識點
- 爬蟲用途
- 爬蟲流程介紹
- 需求描述
- Http請求處理
- http基礎知識介紹
- http狀態碼
- httpheader
- java原生態處理http
- URL類
- 獲取URL請求狀態
- 模擬Http請求
- apache httpclient
- Httpclient1
- httpclient2
- httpclient3
- httpclient4
- httpclient5
- httpclient6
- okhttp
- OKhttp使用教程
- 技術使用
- java執行javascript
- 網頁解析
- Xpath介紹
- HtmlCleaner
- HtmlCleaner介紹
- HtmlCleaner使用
- HtmlParser
- HtmlParser介紹
- Jsoup
- 解析和遍歷一個HTML文檔
- 解析一個HTML字符串
- 解析一個body片斷
- 從一個URL加載一個Document
- 從一個文件加載一個文檔
- 使用DOM方法來遍歷一個文檔
- 使用選擇器語法來查找元素
- 從元素抽取屬性,文本和HTML
- 處理URLs
- 示例程序 獲取所有鏈接
- 設置屬性的值
- 設置一個元素的HTML內容
- 消除不受信任的HTML (來防止XSS攻擊)
- 正則表達式
- elasticsearch筆記
- 下載安裝elasticsearch
- 檢查es服務健康