【问题标题】:Subsequent httpClient calls return initial calls results随后的 httpClient 调用返回初始调用结果
【发布时间】:2014-11-17 14:43:38
【问题描述】:

我在一个名为 HttpHelper 的类中拥有这些方法。现在初始调用验证用户凭据并返回 true。这是意料之中的。下一个调用是注册用户。这似乎很顺利,没有打嗝,是返回新的用户 ID。它不再返回用户 ID,而是再次返回 true。几乎就像它被缓存并且只是从初始调用返回结果。有人对为什么会发生这种情况有任何想法吗?

private static CookieStore sCookieStore;

private static String invoke(HttpUriRequest request)
            throws ClientProtocolException, IOException {
        String result = null;
        DefaultHttpClient httpClient = new DefaultHttpClient();

        // restore cookie
        if (sCookieStore != null) {
            httpClient.setCookieStore((org.apache.http.client.CookieStore) sCookieStore);
        }

        //request.addHeader("Host", "localhost");
        HttpResponse response = httpClient.execute(request);

        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
        for (String s = reader.readLine(); s != null; s = reader.readLine()) {
            builder.append(s);
        }
        result = builder.toString();
        Log.d(TAG, "result is ( " + result + " )");

        // store cookie
        sCookieStore = (CookieStore) ((AbstractHttpClient) httpClient).getCookieStore();
        return result;
    }

public static String invokeGet(String action, List<NameValuePair> params) {
        try {
            StringBuilder sb = new StringBuilder(API_URL);
            sb.append(action);
            if (params != null) {
                for (NameValuePair param : params) {
                    sb.append("?");
                    sb.append(param.getName());
                    sb.append("=");
                    sb.append(param.getValue());
                }
            }
            Log.d(TAG, "url is" + sb.toString());
            //HttpGet httpGet = new HttpGet(URLEncoder.encode(sb.toString(), "UTF-8"));
            HttpGet httpGet = new HttpGet(sb.toString());

            return invoke(httpGet);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }

        return null;
    }

    public static String invokeGet(String action) {
        return invokeGet(action, null);
    }

这是我正在拨打的电话。如上所述,authResult 变量将导致字符串结果为真。 nextResult 应该保存用户 ID 值,而是像初始请求一样保存值 true:

String authResult = HttpHelper.invokeGet("<url to validate user>");

        if (this.URL.indexOf("register") > -1)      
            String nextResult = HttpHelper.invokeGet(this.URL);
        else
            String nextResult = HttpHelper.invokeGet(this.URL);

更新:添加到sCookieStore 变量中。

更新 2:添加通过 API (MVC .NET) 调用的方法:

authResult 变量会得到这个结果:

public bool Get(String userName, String userPassword)
        {
            Task<IdentityUser> iu = _repo.FindUser(userName, userPassword);

            if (iu != null)
            {
                FormsAuthentication.SetAuthCookie(userName, false);
                return true;
            }

            return false;
        }

nextResult 变量应该得到这个结果:

[HttpGet]
    [AllowAnonymous]
    public async Task<IHttpActionResult> RegisterUser(String userName, String userPassword, String huh)
    {
        UserModel userModel = new UserModel();
        userModel.ConfirmPassword = userPassword;
        userModel.UserName = userName;
        userModel.Password = userPassword;

        String userID = "";

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        IdentityResult result = await _repo.RegisterUser(userModel);

        IHttpActionResult errorResult = GetErrorResult(result);

        if (errorResult != null)
        {
            return errorResult;
        }
        else
        {
            Task<IdentityUser> iu = _repo.FindUser(userModel.UserName, userModel.Password);

            using (var context = new AuthContext())
            {
                var userStore = new UserStore<IdentityUser>(context);
                var userManager = new UserManager<IdentityUser>(userStore);

                userID = iu.Result.Id;

                result = await userManager.AddToRoleAsync(userID, "Users");

                errorResult = GetErrorResult(result);

                if (errorResult != null)
                {
                    return errorResult;
                }
            }
        }

        return Ok("userID:" + userID);
    }

【问题讨论】:

  • 我假设您点击了正确的 URL 并使用 curl 测试了他们的回复,对吧?另外,请注意您在for (NameValuePair param : params) { sb.append("?");.. 处有一个错误(您现在正在跳过该分支,但稍后会遇到)。
  • @Vlad - 我使用的 API 是用 .NET MVC 编写的。我通过 Visual Studio 2013 对其进行了测试,那里一切正常。我刚刚包含的 NameValuePair 是因为到目前为止,我什至还没有使用该方法的那一部分来传递参数。所以我什至还没有调试过那部分代码。仅由于我当前正在使用的另一个 invokeGet 和传递 null 而添加。

标签: java androidhttpclient


【解决方案1】:

看起来 authResult 将触发 invokeGet 2 次,给它相同的参数 (this.URL)。在 invokeGet 中,变量 sb 将是 this.URL 两次函数触发。

这让我有点好奇:

   // restore cookie
    if (sCookieStore != null) {
        httpClient.setCookieStore((org.apache.http.client.CookieStore) sCookieStore);
    }

然后在最后,

// store cookie
    sCookieStore = (CookieStore) ((AbstractHttpClient) httpClient).getCookieStore();

sCookieStore 是什么时候定义的?可能是 cookie 没有被正确处理,而您正在建立两个新的连接。如果获取和设置 cookie 是个问题,最好在 invoke 开始时获取 cookie,然后在末尾设置新的。

【讨论】:

  • authResult 不会触发 invokeGet 2 次。初始调用是验证用户。然后根据 URL,如果它包含单词 register,它就会做它的事情。这稍后将更改为 invokePost ,但仅用于测试目的以使代码正常工作,因此我也可以通过浏览器进行测试。 sCookieStore 是该静态类的静态变量。我需要将该 cookie 传递给每个请求,因为初始用户验证会设置该变量,然后将用于通过 API 对后续请求进行授权。
  • 我还通过android中的调试器和invoke方法检查了请求变量,它确实显示了每个实例使用的正确URL。
  • 对不起,我不清楚我的意思 - 从你的描述中听起来你多次触发 authResult。是这样吗?
  • 它的描述方式相同,只是顶部的措辞不同,正如我提到的 nextResult 在它应该保存用户 ID 时保存 authResult 的值。调试器中的所有内容都显示每个请求在执行执行命令之前都有相应的 URL 值。这就是回报变得混乱的东西。因此,至少在变量本身内,httpClient 拥有所有正确的信息。从它发送和返回的点来看,就是发生混淆的地方。至少,从我在调试中看到的情况来看。
  • 我完全删除了 cookie 的设置,只是为了确保它不会导致任何问题,并且同样的结果再次发生。因此,导致混淆的不是 httpClient 上的 cookie 关联。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多