0

我在 Android 应用程序中使用 Apache HttpClient 时遇到了一个奇怪的问题。

我的应用程序需要登录到网站并获取一些数据,然后注销。

我当前的代码如下所示:

public class BlueClient {
    private String hostUrl;
    private DefaultHttpClient client;
    private HttpContext localContext;


    public BlueClient(String hostUrl,DefaultHttpClient httpClient,HttpContext localContext) {

        this.hostUrl = hostUrl;
        this.client = httpClient;
        this.localContext = localContext;

    }

    public boolean doLogin(String userName,String password){
        String url = getHostUrl()+"do_login";//loggin will set a session cookie
        HttpPost post = new HttpPost(url);

        try {
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("username",userName));
            nameValuePairs.add(new BasicNameValuePair("password",password));
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = client.execute(post,localContext);

            //ok now if response is ok then return true

        } catch (Exception e) {

        }
        return false;
    }

    public MyStuff getMyStuff(){
        String url = getHostUrl()+"/getMyStuff/"; //this url requires authentication. the sesion cookie should do that 
        HttpGet get = new HttpGet(url);
        try {
            HttpResponse response = client.execute(get,localContext);
            //ok get my stuff from response and return
        } catch (Exception e) {

        }
        return null;
    }
    public boolean doLogout(){
    String url = getHostUrl()+"do_logout";//it clears the cookie so the session is invalidated
    HttpGet get = new HttpGet(url);
    try {
        HttpResponse response = client.execute(get,localContext);
        //ok the cookie is cleared
      }
    } catch (Exception e) {

    }
    return false;
  }
}

当我调用这些函数时,我确实喜欢这样。它适用于模拟器但不适用于设备

HttpContext context = new BasicHttpContext();
CookieStore cookieStore = new BasicCookieStore();
context.setAttribute(ClientContext.COOKIE_STORE,cookieStore);
DefaultHttpClient httpClient = new DefaultHttpClient();

BlueClient myClient = new BlueClient("http://myHost.com/",httpClient,context);

myClient.doLogin("user","pass");
 // it should've printed the cookies set by the server but i get nothing here !
D.log(context.getAttribute(ClientContext.COOKIE_STORE));
// as this is another subsequesnt request it shoud carry the cookies back to the server but as the cookies are not set this function gives me nothig :-(
myClient.getMyStuff();
myClient.doLogout();

任何人都可以对此有所了解。为什么它不能在设备中工作?

4

1 回答 1

0

啊终于找到问题了!

My server runs on CodeIgniter. And CodeIgniter set the expiry date of the session cookie (ci_session) as Netscape cookie draft compliant. And the format is EEE, dd-MMM-yy HH:mm:ss zzz and Default CookiePoicy used by HttpClient is RFC_2109. So when the httpClient tries to parse the cookie data it fails on parsing the expiry date. I had to explicitly set the Cookie Policy and date format.

So my final code looks like this:

BasicHttpParams params = new BasicHttpParams();
String[] dateFormats = {"EEE, dd-MMM-yy HH:mm:ss zzz"};
params.setParameter(CookieSpecPNames.DATE_PATTERNS,Arrays.asList(dateFormats));

DefaultHttpClient httpClient = new DefaultHttpClient(params);
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.NETSCAPE);//explicitly set the cookie policy

HttpContext context = new BasicHttpContext();
CookieStore cookieStore = new BasicCookieStore();
context.setAttribute(ClientContext.COOKIE_STORE,cookieStore);


BlueClient myClient = new BlueClient("http://myHost.com/",httpClient,context);

myClient.doLogin("user","pass");
myClient.getMyStuff();//now i get my stuff !
myClient.doLogout();

Hope it saves someone's time :)

于 2012-11-23T07:08:58.070 回答