Retrofit2.0 完美同步Cookie实现免登录

<div id="article_content" class="article_content">
        <div class="markdown_views"><p>原文出自csdn: <br>
<a href="http://blog.csdn.net/sk719887916/article/details/51700659">http://blog.csdn.net/sk719887916/article/details/51700659</a></p>


<h2 id="cookie"><a name="t0"></a>Cookie</h2>


<p>Cookies是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术。Cookies是当你浏览某网站时,由Web服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。当你再次来到该网站时,网站通过读取Cookies,得知你的相关信息,就可以做出相应的动作,如在页面显示欢迎你的标语,或者让你不用输入ID、密码就直接登录等等。</p>


<p>从本质上讲,它可以看作是你的身份证。但Cookies不能作为代码执行,也不会传送病毒,且为你所专有,并只能由提供它的服务器来读取。保存的信息片断以“名/值”对(name-value pairs)的形式储存,一个“名/值”对仅仅是一条命名的数据。一个网站只能取得它放在你的电脑中的信息,它无法从其它的Cookies文件中取得信息,也无法得到你的电脑上的其它任何东西。</p>


<p>Cookies中的内容大多数经过了加密处理,因此一般用户看来只是一些毫无意义的字母数字组合,只有服务器的CGI处理程序才知道它们真正的含义。</p>


<p>Cookie也是http的会话跟踪技术,也包含web端的session。cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力.</p>


<h2 id="自定义cookie"><a name="t1"></a>自定义cookie</h2>


<p>HttpClient中大家都知道加入cookie的方式</p>






<pre class="prettyprint" name="code"><code class="hljs axapta has-numbering">AsyncHttpClient <span class="hljs-keyword">client</span> = <span class="hljs-keyword">new</span> AsyncHttpClient();
PersistentCookieStore myCookieStore = <span class="hljs-keyword">new</span> PersistentCookieStore(MainActivity.<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">client</span>.setCookieStore(myCookieStore);</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>


<p>因此Retrofit中需自我实现一个PersistentCookieStore 用来储存OkHttpCookies。</p>


<h2 id="persistentcookiestore"><a name="t2"></a>PersistentCookieStore</h2>






<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-javadoc">/**
  * Created by LIUYONGKUI on 2016-06-09.
  */</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersistentCookieStore</span> {</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String LOG_TAG = <span class="hljs-string">"PersistentCookieStore"</span>;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String COOKIE_PREFS = <span class="hljs-string">"Cookies_Prefs"</span>;


<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Map&lt;String, ConcurrentHashMap&lt;String, Cookie&gt;&gt; cookies;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> SharedPreferences cookiePrefs;




<span class="hljs-keyword">public</span> <span class="hljs-title">PersistentCookieStore</span>(Context context) {
    cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, <span class="hljs-number">0</span>);
    cookies = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();


    <span class="hljs-comment">//将持久化的cookies缓存到内存中 即map cookies</span>
    Map&lt;String, ?&gt; prefsMap = cookiePrefs.getAll();
    <span class="hljs-keyword">for</span> (Map.Entry&lt;String, ?&gt; entry : prefsMap.entrySet()) {
        String[] cookieNames = TextUtils.split((String) entry.getValue(), <span class="hljs-string">","</span>);
        <span class="hljs-keyword">for</span> (String name : cookieNames) {
            String encodedCookie = cookiePrefs.getString(name, <span class="hljs-keyword">null</span>);
            <span class="hljs-keyword">if</span> (encodedCookie != <span class="hljs-keyword">null</span>) {
                Cookie decodedCookie = decodeCookie(encodedCookie);
                <span class="hljs-keyword">if</span> (decodedCookie != <span class="hljs-keyword">null</span>) {
                    <span class="hljs-keyword">if</span> (!cookies.containsKey(entry.getKey())) {
                        cookies.put(entry.getKey(), <span class="hljs-keyword">new</span> ConcurrentHashMap&lt;String, Cookie&gt;());
                    }
                    cookies.get(entry.getKey()).put(name, decodedCookie);
                }
            }
        }
    }
}


<span class="hljs-keyword">protected</span> String <span class="hljs-title">getCookieToken</span>(Cookie cookie) {
    <span class="hljs-keyword">return</span> cookie.name() + <span class="hljs-string">"@"</span> + cookie.domain();
}


<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">add</span>(HttpUrl url, Cookie cookie) {
    String name = getCookieToken(cookie);


    <span class="hljs-comment">//将cookies缓存到内存中 如果缓存过期 就重置此cookie</span>
    <span class="hljs-keyword">if</span> (!cookie.persistent()) {
        <span class="hljs-keyword">if</span> (!cookies.containsKey(url.host())) {
            cookies.put(url.host(), <span class="hljs-keyword">new</span> ConcurrentHashMap&lt;String, Cookie&gt;());
        }
        cookies.get(url.host()).put(name, cookie);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">if</span> (cookies.containsKey(url.host())) {
            cookies.get(url.host()).remove(name);
        }
    }


    <span class="hljs-comment">//将cookies持久化到本地</span>
    SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
    prefsWriter.putString(url.host(), TextUtils.join(<span class="hljs-string">","</span>, cookies.get(url.host()).keySet()));
    prefsWriter.putString(name, encodeCookie(<span class="hljs-keyword">new</span> OkHttpCookies(cookie)));
    prefsWriter.apply();
}
<span class="hljs-keyword">public</span> List&lt;Cookie&gt; <span class="hljs-title">get</span>(HttpUrl url) {
    ArrayList&lt;Cookie&gt; ret = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
    <span class="hljs-keyword">if</span> (cookies.containsKey(url.host()))
        ret.addAll(cookies.get(url.host()).values());
    <span class="hljs-keyword">return</span> ret;
}


<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">removeAll</span>() {
    SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
    prefsWriter.clear();
    prefsWriter.apply();
    cookies.clear();
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}


<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">remove</span>(HttpUrl url, Cookie cookie) {
    String name = getCookieToken(cookie);


    <span class="hljs-keyword">if</span> (cookies.containsKey(url.host()) &amp;&amp; cookies.get(url.host()).containsKey(name)) {
        cookies.get(url.host()).remove(name);


        SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
        <span class="hljs-keyword">if</span> (cookiePrefs.contains(name)) {
            prefsWriter.remove(name);
        }
        prefsWriter.putString(url.host(), TextUtils.join(<span class="hljs-string">","</span>, cookies.get(url.host()).keySet()));
        prefsWriter.apply();


        <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
    }
}


<span class="hljs-keyword">public</span> List&lt;Cookie&gt; <span class="hljs-title">getCookies</span>() {
    ArrayList&lt;Cookie&gt; ret = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
    <span class="hljs-keyword">for</span> (String key : cookies.keySet())
        ret.addAll(cookies.get(key).values());


    <span class="hljs-keyword">return</span> ret;
}


<span class="hljs-javadoc">/**
 * cookies 序列化成 string
 *
 *<span class="hljs-javadoctag"> @param</span> cookie 要序列化的cookie
 *<span class="hljs-javadoctag"> @return</span> 序列化之后的string
 */</span>
<span class="hljs-keyword">protected</span> String <span class="hljs-title">encodeCookie</span>(OkHttpCookies cookie) {
    <span class="hljs-keyword">if</span> (cookie == <span class="hljs-keyword">null</span>)
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
    ByteArrayOutputStream os = <span class="hljs-keyword">new</span> ByteArrayOutputStream();
    <span class="hljs-keyword">try</span> {
        ObjectOutputStream outputStream = <span class="hljs-keyword">new</span> ObjectOutputStream(os);
        outputStream.writeObject(cookie);
    } <span class="hljs-keyword">catch</span> (IOException e) {
        Log.d(LOG_TAG, <span class="hljs-string">"IOException in encodeCookie"</span>, e);
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
    }


    <span class="hljs-keyword">return</span> byteArrayToHexString(os.toByteArray());
}


<span class="hljs-javadoc">/**
 * 将字符串反序列化成cookies
 *
 *<span class="hljs-javadoctag"> @param</span> cookieString cookies string
 *<span class="hljs-javadoctag"> @return</span> cookie object
 */</span>
<span class="hljs-keyword">protected</span> Cookie <span class="hljs-title">decodeCookie</span>(String cookieString) {
    <span class="hljs-keyword">byte</span>[] bytes = hexStringToByteArray(cookieString);
    ByteArrayInputStream byteArrayInputStream = <span class="hljs-keyword">new</span> ByteArrayInputStream(bytes);
    Cookie cookie = <span class="hljs-keyword">null</span>;
    <span class="hljs-keyword">try</span> {
        ObjectInputStream objectInputStream = <span class="hljs-keyword">new</span> ObjectInputStream(byteArrayInputStream);
        cookie = ((OkHttpCookies) objectInputStream.readObject()).getCookies();
    } <span class="hljs-keyword">catch</span> (IOException e) {
        Log.d(LOG_TAG, <span class="hljs-string">"IOException in decodeCookie"</span>, e);
    } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) {
        Log.d(LOG_TAG, <span class="hljs-string">"ClassNotFoundException in decodeCookie"</span>, e);
    }


    <span class="hljs-keyword">return</span> cookie;
}


<span class="hljs-javadoc">/**
 * 二进制数组转十六进制字符串
 *
 *<span class="hljs-javadoctag"> @param</span> bytes byte array to be converted
 *<span class="hljs-javadoctag"> @return</span> string containing hex values
 */</span>
 <span class="hljs-keyword">protected</span> String <span class="hljs-title">byteArrayToHexString</span>(<span class="hljs-keyword">byte</span>[] bytes) {
    StringBuilder sb = <span class="hljs-keyword">new</span> StringBuilder(bytes.length * <span class="hljs-number">2</span>);
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">byte</span> element : bytes) {
        <span class="hljs-keyword">int</span> v = element &amp; <span class="hljs-number">0xff</span>;
        <span class="hljs-keyword">if</span> (v &lt; <span class="hljs-number">16</span>) {
            sb.append(<span class="hljs-string">'0'</span>);
        }
        sb.append(Integer.toHexString(v));
    }
    <span class="hljs-keyword">return</span> sb.toString().toUpperCase(Locale.US);
}


<span class="hljs-javadoc">/**
 * 十六进制字符串转二进制数组
 *
 *<span class="hljs-javadoctag"> @param</span> hexString string of hex-encoded values
 *<span class="hljs-javadoctag"> @return</span> decoded byte array
 */</span>
<span class="hljs-keyword">protected</span> <span class="hljs-keyword">byte</span>[] <span class="hljs-title">hexStringToByteArray</span>(String hexString) {
    <span class="hljs-keyword">int</span> len = hexString.length();
    <span class="hljs-keyword">byte</span>[] data = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[len / <span class="hljs-number">2</span>];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; len; i += <span class="hljs-number">2</span>) {
        data[i / <span class="hljs-number">2</span>] = (<span class="hljs-keyword">byte</span>) ((Character.digit(hexString.charAt(i), <span class="hljs-number">16</span>) &lt;&lt; <span class="hljs-number">4</span>) + Character.digit(hexString.charAt(i + <span class="hljs-number">1</span>), <span class="hljs-number">16</span>));
    }
    <span class="hljs-keyword">return</span> data;
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li><li>156</li><li>157</li><li>158</li><li>159</li><li>160</li><li>161</li><li>162</li><li>163</li><li>164</li><li>165</li><li>166</li><li>167</li><li>168</li><li>169</li><li>170</li><li>171</li><li>172</li><li>173</li><li>174</li><li>175</li><li>176</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li><li>156</li><li>157</li><li>158</li><li>159</li><li>160</li><li>161</li><li>162</li><li>163</li><li>164</li><li>165</li><li>166</li><li>167</li><li>168</li><li>169</li><li>170</li><li>171</li><li>172</li><li>173</li><li>174</li><li>175</li><li>176</li></ul></pre>


<h2 id="okhttpcookies"><a name="t3"></a>OkHttpCookies</h2>


<p>需要实现序列化的 OkHttpCookies 用来持久OkHttpCookies</p>


<pre class="prettyprint" name="code"><code class="hljs avrasm has-numbering">   <span class="hljs-comment">/**
 * Created by LIUYONGKUI on 2016-05-20.
  */</span>
public class OkHttpCookies implements Serializable {


private transient final Cookie cookies<span class="hljs-comment">;</span>
private transient Cookie clientCookies<span class="hljs-comment">;</span>


public OkHttpCookies(Cookie cookies) {
    this<span class="hljs-preprocessor">.cookies</span> = cookies<span class="hljs-comment">;</span>
}


public Cookie getCookies() {
    Cookie bestCookies = cookies<span class="hljs-comment">;</span>
    if (clientCookies != null) {
        bestCookies = clientCookies<span class="hljs-comment">;</span>
    }
    return bestCookies<span class="hljs-comment">;</span>
}


private void writeObject(ObjectOutputStream <span class="hljs-keyword">out</span>) throws IOException {
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeObject</span>(cookies<span class="hljs-preprocessor">.name</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeObject</span>(cookies<span class="hljs-preprocessor">.value</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeLong</span>(cookies<span class="hljs-preprocessor">.expiresAt</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeObject</span>(cookies<span class="hljs-preprocessor">.domain</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeObject</span>(cookies<span class="hljs-preprocessor">.path</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeBoolean</span>(cookies<span class="hljs-preprocessor">.secure</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeBoolean</span>(cookies<span class="hljs-preprocessor">.httpOnly</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeBoolean</span>(cookies<span class="hljs-preprocessor">.hostOnly</span>())<span class="hljs-comment">;</span>
    <span class="hljs-keyword">out</span><span class="hljs-preprocessor">.writeBoolean</span>(cookies<span class="hljs-preprocessor">.persistent</span>())<span class="hljs-comment">;</span>
}
private void readObject(ObjectInputStream <span class="hljs-keyword">in</span>) throws IOException, ClassNotFoundException {
    String name = (String) <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readObject</span>()<span class="hljs-comment">;</span>
    String value = (String) <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readObject</span>()<span class="hljs-comment">;</span>
    long expiresAt = <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readLong</span>()<span class="hljs-comment">;</span>
    String domain = (String) <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readObject</span>()<span class="hljs-comment">;</span>
    String path = (String) <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readObject</span>()<span class="hljs-comment">;</span>
    boolean secure = <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readBoolean</span>()<span class="hljs-comment">;</span>
    boolean httpOnly = <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readBoolean</span>()<span class="hljs-comment">;</span>
    boolean hostOnly = <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readBoolean</span>()<span class="hljs-comment">;</span>
    boolean persistent = <span class="hljs-keyword">in</span><span class="hljs-preprocessor">.readBoolean</span>()<span class="hljs-comment">;</span>
    Cookie<span class="hljs-preprocessor">.Builder</span> builder = new Cookie<span class="hljs-preprocessor">.Builder</span>()<span class="hljs-comment">;</span>
    builder = builder<span class="hljs-preprocessor">.name</span>(name)<span class="hljs-comment">;</span>
    builder = builder<span class="hljs-preprocessor">.value</span>(value)<span class="hljs-comment">;</span>
    builder = builder<span class="hljs-preprocessor">.expiresAt</span>(expiresAt)<span class="hljs-comment">;</span>
    builder = hostOnly ? builder<span class="hljs-preprocessor">.hostOnlyDomain</span>(domain) : builder<span class="hljs-preprocessor">.domain</span>(domain)<span class="hljs-comment">;</span>
    builder = builder<span class="hljs-preprocessor">.path</span>(path)<span class="hljs-comment">;</span>
    builder = secure ? builder<span class="hljs-preprocessor">.secure</span>() : builder<span class="hljs-comment">;</span>
    builder = httpOnly ? builder<span class="hljs-preprocessor">.httpOnly</span>() : builder<span class="hljs-comment">;</span>
    clientCookies =builder<span class="hljs-preprocessor">.build</span>()<span class="hljs-comment">;</span>
    }
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li></ul></pre>


<h2 id="自定义cookiemanger"><a name="t4"></a>自定义CookieManger</h2>


<p>实现有一个自定义的CookieManger来管理cookies,实现以K-V结构获取set、getCookier</p>


<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CookieManger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">CookieJar</span> {</span>




<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String APP_PLATFORM = <span class="hljs-string">"app-platform"</span>;




<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Context mContext;


<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> PersistentCookieStore cookieStore;


<span class="hljs-keyword">public</span> <span class="hljs-title">CookieManger</span>(Context context) {
    mContext = context;
    <span class="hljs-keyword">if</span> (cookieStore == <span class="hljs-keyword">null</span> ) {
        cookieStore = <span class="hljs-keyword">new</span> PersistentCookieStore(mContext);
    }


}


<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveFromResponse</span>(HttpUrl url, List&lt;Cookie&gt; cookies) {
    <span class="hljs-keyword">if</span> (cookies != <span class="hljs-keyword">null</span> &amp;&amp; cookies.size() &gt; <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">for</span> (Cookie item : cookies) {
            cookieStore.add(url, item);
        }
    }
}


<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> List&lt;Cookie&gt; <span class="hljs-title">loadForRequest</span>(HttpUrl url) {
    List&lt;Cookie&gt; cookies =cookieStore.get(url);
    <span class="hljs-keyword">return</span> cookies;
}


<span class="hljs-keyword">static</span> class Customer {


    <span class="hljs-keyword">private</span> String userID;
    <span class="hljs-keyword">private</span> String token;


    <span class="hljs-keyword">public</span> <span class="hljs-title">Customer</span>(String userID, String token) {
        <span class="hljs-keyword">this</span>.userID = userID;
        <span class="hljs-keyword">this</span>.token = token;
    }


    <span class="hljs-keyword">public</span> String <span class="hljs-title">getUserID</span>() {
        <span class="hljs-keyword">return</span> userID;
    }


    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setUserID</span>(String userID) {
        <span class="hljs-keyword">this</span>.userID = userID;
    }


    <span class="hljs-keyword">public</span> String <span class="hljs-title">getToken</span>() {
        <span class="hljs-keyword">return</span> token;
    }


    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setToken</span>(String token) {
        <span class="hljs-keyword">this</span>.token = token;
    }


}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li></ul></pre>


<h2 id="retrofit加入cookie"><a name="t5"></a>Retrofit加入cookie</h2>


<pre class="prettyprint" name="code"><code class="hljs avrasm has-numbering">OkHttpClient okHttpClient = new OkHttpClient<span class="hljs-preprocessor">.Builder</span>()
            <span class="hljs-preprocessor">.addNetworkInterceptor</span>(
                    new HttpLoggingInterceptor()<span class="hljs-preprocessor">.setLevel</span>(HttpLoggingInterceptor<span class="hljs-preprocessor">.Level</span><span class="hljs-preprocessor">.HEADERS</span>))
            <span class="hljs-preprocessor">.cookieJar</span>(new CookieManger(context))
            <span class="hljs-preprocessor">.addInterceptor</span>(loginInterceptor)
            <span class="hljs-preprocessor">.connectTimeout</span>(DEFAULT_TIMEOUT, TimeUnit<span class="hljs-preprocessor">.SECONDS</span>)
            <span class="hljs-preprocessor">.build</span>()<span class="hljs-comment">;</span>


    Retrofit retrofit = new Retrofit<span class="hljs-preprocessor">.Builder</span>()
            <span class="hljs-preprocessor">.client</span>(okHttpClient)
            <span class="hljs-preprocessor">.build</span>()<span class="hljs-comment">;</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul></pre>


<h2 id="总结"><a name="t6"></a>总结</h2>


<p>实现加入cookies持久,实现免登陆基本步骤</p>


<pre class="prettyprint" name="code"><code class="hljs erlang-repl has-numbering"><span class="hljs-number">1</span> 实现可序列化的<span class="hljs-variable">OkHttpcookies</span> 
<span class="hljs-number">2</span> 实现储存<span class="hljs-variable">OkHttpcookies</span>的<span class="hljs-variable">PersistentCookieStore</span> 
<span class="hljs-number">3</span> 实现<span class="hljs-function_or_atom">cookies</span>管理工具<span class="hljs-variable">CookieManger</span> 
<span class="hljs-number">4</span> 构建<span class="hljs-variable">OKHttpClient</span> 
<span class="hljs-number">5</span> <span class="hljs-variable">Retrofit</span>加入自定义的<span class="hljs-ok">ok</span><span class="hljs-variable">HttpClient</span> 
<span class="hljs-number">6</span> 直接调用<span class="hljs-variable">RetrofitClient</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul></pre></div>
        <script type="text/javascript">
            $(function () {
                $('pre.prettyprint code').each(function () {
                    var lines = $(this).text().split('\n').length;
                    var $numbering = $('<ul></ul>').addClass('pre-numbering').hide();
                    $(this).addClass('has-numbering').parent().append($numbering);
                    for (i = 1; i <= lines; i++) {
                        $numbering.append($('<li></li>').text(i));
                    };
                    $numbering.fadeIn(1700);
                });
            });
        </script>
   
</div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中使用 Retrofit 上传图片可以通过 `@Multipart` 和 `@Part` 注解实现。以下是 Retrofit 2.0 实现图文上传的方法总结: 1. 添加依赖库 在项目的 `build.gradle` 文件中添加以下依赖库: ```groovy implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' ``` 2. 创建 Retrofit 实例 ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); ``` 3. 创建 API 接口 ```java public interface ApiService { @Multipart @POST("upload") Call<ResponseBody> upload( @Part("description") RequestBody description, @Part MultipartBody.Part file); } ``` 其中,`@Multipart` 注解表示这是一个包含文本和文件的表单;`@POST("upload")` 表示上传的 URL 地址;`@Part("description") RequestBody description` 表示上传的文本参数,`description` 是参数名,可以自己定义;`@Part MultipartBody.Part file` 表示上传的文件参数。 4. 创建请求参数 ```java File file = new File(filePath); RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile); RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), "description"); ``` 5. 发送网络请求 ```java ApiService apiService = retrofit.create(ApiService.class); Call<ResponseBody> call = apiService.upload(description, body); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { // 成功上传后的处理 } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 上传失败后的处理 } }); ``` 以上就是 Retrofit 2.0 实现图文上传的方法总结。注意,在 `AndroidManifest.xml` 文件中需要添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值