Android 上的 HTTPPost 与 HttpUrlConnection POST

HTTPPost vs HttpUrlConnection POST on Android

我正在尝试在我的 Android 应用程序中从 Apache HTTP 转移到 HttpUrlConnection。我被困住了,我试着到处寻找,但我无法通过它。这就是我正在尝试的。

下面是我的 HTTP 代码:

HttpParams timeoutParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(timeoutParams, 60000);
HttpConnectionParams.setSoTimeout(timeoutParams, 60000);

DefaultHttpClient httpClient = null;
httpClient = new DefaultHttpClient(timeoutParams);
Cookie podCookie = getPodCookie();
    if (podCookie != null) {
        httpClient.getCookieStore().addCookie(podCookie);
    }
HttpPost postMethod = null;
postMethod.addHeader("Authorization", "<auth-header>");
try {
    List<NameValuePair> nvps = new ArrayList<NameValuePair>();
    for (Entry<String, String> entry : parameters.entrySet()) {
        nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
    }
    String queryString = URLEncodedUtils.format(nvps, HTTP.UTF_8);
    String modUrl = url + "?" + queryString;
    postMethod = new HttpPost(modUrl);

StringEntity entity = new StringEntity(<String JSON to send>, HTTP.UTF_8);
postMethod.setEntity(entity);
postMethod.setHeader("Content-type", "application/json");
HttpResponse reply = httpClient.execute(postMethod);

这是与上述代码等效的 HttpUrlConnection:

List<NameValuePair> nvps = new ArrayList<NameValuePair>();
    for (Entry<String, String> entry: parameters.entrySet()) {
        nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
     }

String queryString = URLEncodedUtils.format(nvps, HTTP.UTF_8);
String modUrl = baseUrl + "?" + queryString;
HttpURLConnection urlConnection = null;
try {
    URL url1 = new URL(modUrl);
    urlConnection = (HttpURLConnection) url1.openConnection();
    CookieManager cookieManager = new CookieManager();
    CookieHandler.setDefault(cookieManager);
    cookieManager.getCookieStore().add(new URI(url), podCookie);
    urlConnection.setConnectTimeout(60000);
    urlConnection.setReadTimeout(60000);
    urlConnection.setDoOutput(true);
    urlConnection.setRequestMethod("POST");

    urlConnection.setRequestProperty("Authorization", <auth-header>);
    urlConnection.setRequestProperty("Content-Type", "application/json");

    OutputStream os = urlConnection.getOutputStream();
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
    writer.write(<String JSON to send>);
    writer.flush()
    writer.close();
    os.close();

    InputStream is = new BufferedInputStream(urlConnection.getInputStream());
    String responseString = WebService.convertInputStreamToString(is);

当我尝试上述操作时,我得到了 401 Unauthorized error。我正在使用 Charles 和 headers 是一样的。

当我尝试在 BufferedWriter 而不是 URL 中添加查询参数时,我将 url 更改为基础 url,如下所示:

URL url1 = new URL(baseUrl);

并将以下行添加到 writer,如下所示:

writer.write(modUrl)

当我这样做时,我得到一个 500 Internal Server Error

在这两种情况下,我都得到一个 IOException,它是 InputStream 行上的 FileNotFoundException

关于如何解决这个问题有什么想法吗?

您应该从成功的 httpclient 调用中转储 headers,这样您就可以确切地知道通过 OK 请求发送了哪些 headers。

不清楚你是如何设置的 "Authorization" header

不清楚 'StringEntity' 中设置了什么 Json 值。

在尝试使用 HttpUrlConnection 之前,您应该确切地知道良好调用(httpClient 调用或 Curl CLI 调用)中发送的内容。然后在那边设置相同的 headers,将相同的 JSON 写入 Connections 的 outputStream,您应该会得到相同的结果。

你的两个 headers 和你的 JSON 实体在 curl.-d 开关值中的卷曲表达式....

curl -v -X POST \
  -H "Content-type: application/json" \
  -H "Authorization: aValueforAuth" \
  -d '{"score":1337,"playerName":"Sean Plott",...}' \
  http://domain/path?parm1=$urlEncodedVal-1&parm2=$urlEncodedVal-2