【问题标题】:Can't POST using loopj AsyncHttpClient and an authorization header无法使用 loopj AsyncHttpClient 和授权标头发布
【发布时间】:2015-07-17 04:27:06
【问题描述】:

我正在使用 loopj (1.4.7) 和 AsyncHttpClient 将 Json 发布到 Web API 服务器。我的(简化的)代码是:

private void createCode() {
    // 1. Get the current data and time
    DateFormat df = DateFormat.getDateTimeInstance();
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    String gmtTime = df.format(new Date());

    // 2. Setup few things
    AsyncHttpClient client = new AsyncHttpClient();
    Context context = this.getApplicationContext();
    connCode = "1234";

    JSONObject jsonData = new JSONObject();
    try {
        jsonData.put("ClientCode", connCode);
        jsonData.put("CodeCreated", gmtTime);
    } catch (Exception ex) {
        // Should not really happen
    }

    // 3. Authorization/Authentication
    String userName = "TestUser";
    String userPassword = "TestPassword";
    String userNamePassword = userName + ":" + userPassword;
    byte[] loginString = userNamePassword.getBytes();
    String loginStringEncoded = Base64.encodeToString(loginString, Base64.DEFAULT);

    client.setAuthenticationPreemptive(true);

    // This is the line that cause the problem
    client.addHeader("Authorization", loginStringEncoded);

    // 4. Setup various options
    StringEntity entity = null;
    try {
        entity = new StringEntity(jsonData.toString());
    } catch (UnsupportedEncodingException e) {
        return;
    }
    entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

    // 5. Post the code to the database
    client.post(context, CODE_URL, entity, "application/json", new JsonHttpResponseHandler() {

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            // TODO - Process results...
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, java.lang.Throwable throwable, org.json.JSONArray errorResponse) {
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, java.lang.Throwable throwable, org.json.JSONObject errorResponse) {
        }
    });
}

响应是“400 - Bad Request”,因为如果我使用"Authorization" 标头,并非所有内容都可以到达服务器。服务器上显示的是(使用 Fiddler 验证):

{"ClientCode":"1234","CodeCreated":"Jul 17, 2015 1:03:00 AM

如果我去掉 "client.addHeader("Authorization", loginStringEncoded);" 行,一切正常,服务器接收所有内容(但我需要 Authorization 标头来限制访问):

{"ClientCode":"1234","CodeCreated":"Jul 17, 2015 1:10:00 AM"}

我可以看出服务器正在正确处理授权,但由于缺少 "}",响应失败。在执行“client.post”命令之前,我已经验证了整个字符串是“实体”变量的一部分。

如果有什么不同,我在 Mac 上运行 Android Studio,并且我已使用 WireShark 验证,当 Mac 连接到 @987654328 时,缺少的 "}" 已经不存在@。 可能是什么原因造成的?类似的设置适用于GET,但我无法使其适用于POST。有没有更好的方法来做到这一点? 谢谢。

【问题讨论】:

  • 您找到合适的解决方案了吗?我有同样的问题。

标签: android json asynchttpclient android-async-http loopj


【解决方案1】:

这对我有用:

 AsyncHttpClient client2 = new SyncHttpClient();
//check if needs this header or I can take off this and leave just the url+token2
                client2.addHeader("x-auth-token", token2);

                client2.post(String.valueOf(url), params, new BaseJsonHttpResponseHandler(String.valueOf(Looper.getMainLooper())) {

                    /**
                     * Base abstract method, handling defined generic type
                     *
                     * @param statusCode      HTTP status line
                     * @param headers         response headers
                     * @param rawJsonResponse string of response, can be null
                     * @param response        response returned by {@link #parseResponse(String, boolean)}
                     */
                    @Override
                    public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, String rawJsonResponse, Object response) {

                        onPostExecute((JSONObject)response);

                    }

                    /**
                     * Base abstract method, handling defined generic type
                     *
                     * @param statusCode    HTTP status line
                     * @param headers       response headers
                     * @param throwable     error thrown while processing request
                     * @param rawJsonData   raw string data returned if any
                     * @param errorResponse response returned by {@link #parseResponse(String, boolean)}
                     */
                    @Override
                    public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, Throwable throwable, String rawJsonData, Object errorResponse) {

                    }

                    /**
                     * Should return deserialized instance of generic type, may return object for more vague
                     * handling
                     *
                     * @param rawJsonData response string, may be null
                     * @param isFailure   indicating if this method is called from onFailure or not
                     * @return object of generic type or possibly null if you choose so
                     * @throws Throwable allows you to throw anything from within deserializing JSON response
                     */
                    @Override
                    protected Object parseResponse(String rawJsonData, boolean isFailure) throws Throwable {
                        return null;
                    }

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 2020-05-22
    • 2021-02-10
    • 2018-12-28
    • 2012-04-24
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 2016-08-24
    相关资源
    最近更新 更多