Use volley to get multiple cookies

Source: Internet
Author: User

Problem description

Recently took over a forum nature of the application, because the traffic is small, network requests frequently, so choose to use volley for refactoring. Because the default volley only reads a cookie, and the item uses 4 cookies, the user login section first uses the original httpclient to save the user's login cookie information.
Refactoring to get and send content part of the refactoring basically can be completed, only the cookie problem, the Internet to find a lot of information, found that many are one-sided, in fact, said the wrong.

Methods found online (does not solve the problem)

Sometimes the server will return multiple Set-cookie values, and volley default only to take the first, if there is a demand, it is necessary to modify volley code, Hurlstack (Sdk_int>9 will walk here) performrequest inside, The default parsing header mode is as follows, multiple values only need to get Header.getvalue (). Get (1) and so on, the specific requirements can be modified by themselves.

new BasicHeader(header.getKey(), header.getValue().get(0));response.addHeader(h);

Above is the online search method, in fact, only said the first step, there is a need to pay attention to the place. But the idea of solving the problem is right:
1. Rewrite or inherit one HurlStack and performRequest() add the cookie to response in the method.
2. Define a model that contains the contents of the request return and a list of cookies.
3. Rewrite a return object is the request of our model above, and in the request parseNetworkResponse method, put the obtained cookie into the model.
There is a little extra attention here, which is not explained in the above method:
In our HurlStack performRequest return is a HttpResponse (header is a list), our cookie is also added to its headers inside. There is no problem at the moment. But the response returned here also undergoes a conversion, because the Request class protected abstract Response<T> parseNetworkResponse(NetworkResponse paramNetworkResponse); parameter is one NetworkResponse , the headers is one Map<String, String> , so this requires that our multiple cookie key cannot be Set-Cookie . Because the cookie in the above code header.getKey() is generally Set-Cookie .
Here are some of the source code:

HurlStack.class

 public  HttpResponse performrequest  (Request<?> Request, map<string, string> additionalheaders) throws  IOException, Authfailureerror {... Basichttpresponse response = new  basichttpresponse (responsestatus); Response.setentity (Entityfromconnection (connection)); for  (Map.entry<string, List<string>> header:connection.getHeaderFields (). EntrySet ()) {if  (Header.getkey ()! = null ) {Head Er h = new  basicheader ((String) Header.getkey (), (String) ((List) Header.getvalue ()) . Get (0 )); Response.AddHeader (h); }} return  response; }

BasicNetwork.class

  privatestaticconvertHeaders(Header[] headers)  {    new HashMap();    for (int0; i < headers.length; i++) {      result.put(headers[i].getName(), headers[i].getValue());    }    return result;  }
My way out.

Key code:
MyHurlStack.class

 PublicHttpResponseperformrequest(Request<?> Request, map<string, string> additionalheaders)throwsIOException, authfailureerror {String url = request.geturl (); HashMap map =NewHashMap ();    Map.putall (Request.getheaders ()); Map.putall (additionalheaders);if( This. murlrewriter! =NULL) {String Parsedurl = This. Murlrewriter.rewriteurl (URL);if(Parsedurl = =NULL) {Throw NewIOException ("URL blocked by rewriter:"+ URL);    } URL = parsedurl; } URL PARSEDURL1 =NewURL (URL); HttpURLConnection connection = This. OpenConnection (PARSEDURL1, request); Iterator responsecode = Map.keyset (). Iterator (); while(Responsecode.hasnext ())      {String protocolversion = (string) responsecode.next ();    Connection.addrequestproperty (ProtocolVersion, (String) Map.get (protocolversion));    } setconnectionparametersforrequest (connection, request); ProtocolVersion ProtocolVersion1 =NewProtocolVersion ("HTTP",1,1);intResponseCode1 = Connection.getresponsecode ();if(ResponseCode1 = =-1) {Throw NewIOException ("Could not retrieve response code from HttpURLConnection."); }Else{Basicstatusline ResponseStatus =NewBasicstatusline (ProtocolVersion1, Connection.getresponsecode (), Connection.getresponsemessage ()); Basichttpresponse response =NewBasichttpresponse (ResponseStatus); Response.setentity (Entityfromconnection (connection)); for(Object o:connection.getheaderfields (). EntrySet ()) {Entry Header = (Entry) o;if(Header.getkey ()! =NULL) {//If it is a Cookie, save it as name = Set-cookie + serial number to ensure that key is different          if(Header.getkey (). Equals ("Set-cookie") {List headerlist = (list) header.getvalue (); for(inti =0; I < headerlist.size (); i++) {Basicheader h =NewBasicheader (String) header.getkey () + I, (string) headerlist.get (i));            Response.AddHeader (h); }          }Else{List headerlist = (list) header.getvalue (); for(Object aheaderlist:headerlist) {Basicheader h =NewBasicheader (String) Header.getkey (), (string) aheaderlist);            Response.AddHeader (h); }          }        }      }returnResponse }  }

MyRequest.class

  //Use regular expressions to extract the substring of the cookie content from the header of the reponse  Private Static FinalPattern pattern = Pattern.compile ("set-cookie\\d*");@Override  protectedResponse<myresponse>Parsenetworkresponse(Networkresponse networkresponse) {Try{Myresponse response =NewMyresponse (); String jsonstring =NewString (Networkresponse.data, Httpheaderparser.parsecharset (networkresponse.headers)); Response.setjsonstring (jsonstring);//Get All Cookieslist<cookie> cookies =NewArraylist<> (); for(String Key:networkResponse.headers.keySet ()) {Matcher Matcher = Pattern.matcher (key);if(Matcher.find ())          {cookiefromresponse = NetworkResponse.headers.get (key); Cookiefromresponse = cookiefromresponse.substring (0, Cookiefromresponse.indexof (";")); String keyvalue[] = Cookiefromresponse.split ("=", -1); Cookie cookie =NewBasicclientcookie (keyvalue[0], keyvalue[1]);        Cookies.add (cookie); }} response.setcookies (cookies);returnResponse.success (Response, Httpheaderparser.parsecacheheaders (Networkresponse)); }Catch(Unsupportedencodingexception e) {returnResponse.error (NewParseError (e)); }  }

MyResponse.class

 Public  class myresponse{  Private StaticString TAG ="Myresponse";Private intStatus =0;PrivateString jsonstring ="";Privatelist<cookie> cookies =NewArraylist<> (); Public int GetStatus() {returnStatus } Public void SetStatus(intStatus) { This. Status = Status; } PublicStringgetjsonstring() {returnjsonstring; } Public void setjsonstring(String jsonstring) { This. jsonstring = jsonstring; } PublicList<cookie>getcookies() {returnCookies } Public void setcookies(List<cookie> Cookies) { This. cookies = cookies; }}

VolleyHelper.class

publicstaticvoidinit(Context context) {    new MyHurlStack());  }
Postscript

At the beginning of the online method just changed the contents of the hurlstack inside, and finally can only get a cookie, here is generally thought to be the reason for the map. Finally find source discovery is really the reason, and then use a stupid method to solve the problem. So according to the source code to analyze and solve the problem is very necessary.
This method just according to our current situation solves the problem, should not solve all the situation, here is just to provide a solution to the idea, if you have a better solution, please leave a message, discuss together.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Use volley to get multiple cookies

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.