Android HTTPPost 返回错误“不允许的方法". [英] Android HTTPPost Returns Error "Method not allowed."

查看:32
本文介绍了Android HTTPPost 返回错误“不允许的方法".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 Android 2.2 应用程序,该应用程序将 json 严格性发布到 ReSTfull 网络服务.

I'm coding an Android 2.2 app that POSTs a json stringentity to a ReSTfull web service.

Fiddler 调用具有相同 Json 的 Web 服务按预期返回,并且具有相同 Json 的 aspx Web 应用程序按预期返回.

Fiddler calls to the web service with identical Json return as expected, and an aspx web application with identical Json returns as expected.

当我查看服务器日志时,我可以看到服务器正在响应具有 307 重定向的初始 POST 动词,然后立即出现 GET 和 405 错误.

When I look at the server logs, I can see that the server is responding to an initial POST verb with a 307 redirect, then immediately a GET and 405 error.

Fiddler 和 aspx 应用程序记录一个带有 307 重定向的 POST,然后立即另一个 POST 和一个 200 OK.

Fiddler and the aspx application log a POST with a 307 redirect, then immediately another POST and a 200 OK.

这是怎么回事?

这是主要活动:

package com.altaver.android_PostJson2;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class PostJson extends Activity {
     private static final String TAG = "MainActivity";
     private static final String URL = "http://web2.altaver.com/sdz/avReSTfulLogin1";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        JSONObject jsonObjSend = new JSONObject();

        try {
         jsonObjSend.put("Pass", "sz");
         jsonObjSend.put("User", "szechman");


         Log.i(TAG, jsonObjSend.toString(2));

        } catch (JSONException e) {
            e.printStackTrace();
        }

        JSONObject jsonObjRecv = HttpClient.SendHttpPost(URL, jsonObjSend);            

//examine JSONObject later
    }
}

这是进行网络服务调用的类代码:

This is the class code doing the web service call:

package com.altaver.android_PostJson2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import android.util.Log;

public class HttpClient {

    private static final String TAG = "HttpClient";


    public static JSONObject SendHttpPost(String URL, JSONObject jsonObjSend) {

          try {
           DefaultHttpClient httpclient = new DefaultHttpClient();

           HttpClientParams.setRedirecting(httpclient.getParams(), true);

           //added cookie policy, wild shot in the dark
           //httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY, >CookiePolicy.RFC_2109);

           HttpPost httpPostRequest = new HttpPost(URL);

           StringEntity se;
           se = new StringEntity(jsonObjSend.toString());

           // Set HTTP parameters
           httpPostRequest.setEntity(se);

           //httpPostRequest.setHeader("User-Agent", >"com.altaver.android_PostJson2");
           httpPostRequest.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; >Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401");

           httpPostRequest.setHeader("Accept", "application/json");
           httpPostRequest.setHeader("Content-Type", "application/json");

           long t = System.currentTimeMillis();
           HttpResponse response = (HttpResponse) >httpclient.execute(httpPostRequest);
           Log.i(TAG, "HTTPResponse received in [" + >(System.currentTimeMillis()-t) + "ms]");

           HttpEntity entity = response.getEntity();

           if (entity != null) {
            InputStream instream = entity.getContent();
            Header contentEncoding = response.getFirstHeader("Content-Encoding");


            String resultString= convertStreamToString(instream);
            instream.close();
            resultString = resultString.substring(1,resultString.length()-1); // >remove wrapping "[" and "]"

            JSONObject jsonObjRecv = new JSONObject(resultString);
            Log.i(TAG,"<jsonobject>
"+jsonObjRecv.toString()+"
</jsonobject>");

            return jsonObjRecv;
           } 

          }
          catch (Exception e)
          {
           e.printStackTrace();
          }
          return null;
         }

    private static String convertStreamToString(InputStream is) {
          /*
           * To convert the InputStream to String we use the >BufferedReader.readLine()
           * method. We iterate until the BufferedReader return null which means
           * there's no more data to read. Each line will appended to a >StringBuilder
           * and returned as String.
           * 
           * (c) public domain: http://senior.ceng.metu.edu.tr/2009/praeda/2009/01>/11/a-simple-restful-client-at-android/
           */
          BufferedReader reader = new BufferedReader(new InputStreamReader(is));
          StringBuilder sb = new StringBuilder();

          String line = null;
          try {
           while ((line = reader.readLine()) != null) {
            sb.append(line + "
");
           }
          } catch (IOException e) {
           e.printStackTrace();
          } finally {
           try {
            is.close();
           } catch (IOException e) {
            e.printStackTrace();
           }
          }
          return sb.toString();
    }
}

推荐答案

在 URL 末尾放置/"会导致重定向发生,因为您的服务器喜欢以/"结尾的 url.您的服务器将您重定向到的 URL 完全支持 POST,但是当客户端根据您的 setRedirecting() 调用进行操作时,客户端正在执行 GET 请求(cURL 使用 -L 开关执行完全相同的操作)修复方法是将URL 末尾的/",或者自己从响应中获取 Location 标头,然后手动发起另一个 POST 请求.

Putting a '/' at the end of URL causes the redirect to happen because your server likes urls that end in '/'. POST is fully supported by the URL your server redirects you to, but the client is executing a GET request when it behaves according to your setRedirecting() call (cURL does the same exact thing with the -L switch) The fix is to either put a '/' at the end of URL, or to grab the Location header from the response yourself and then initiate another POST request manually.

这可以在wireshark中观察到.您可以通过尝试使用浏览器对附加了斜杠的 URL 执行 GET 请求来测试该理论.这将导致浏览器得到 405.这是 Android 的固定代码,此代码使用简单的修复,即在 URL 后附加一个/"(未准备好生产):

This can be observed in wireshark. You can test the theory by trying to perform a GET request with your browser to the URL with a slash appended to it. That will cause the browser to get a 405. Here's the fixed code for Android, this code uses the simple fix of appending a '/' to the URL (not production ready):

 package com.altaver.demo;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class AltaVerDemoActivity extends Activity {
    private static final String TAG = "MainActivity";
    private static final String URL = "http://96.56.2.188/sdz/avReSTfulLogin1/";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        JSONObject jsonObjSend = new JSONObject();
        try {
            jsonObjSend.put("Pass", "sz");
            jsonObjSend.put("User", "szechman");
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HttpClient client = new DefaultHttpClient();
        HttpPost httpPostRequest = new HttpPost(URL);
        httpPostRequest.setHeader("User-Agent", "com.altaver.android_PostJson2");
        httpPostRequest.setHeader("Accept", "application/json");
        httpPostRequest.setHeader("Content-Type", "application/json");
        StringEntity se = null;
        try {
            se = new StringEntity(jsonObjSend.toString());
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        httpPostRequest.setEntity(se);
        HttpResponse response = null;
        try {
            response = client.execute(httpPostRequest);
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            Toast.makeText(getApplicationContext(),
                    "Please check your internet connection",
                    Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        BasicResponseHandler responseHandler = new BasicResponseHandler();
        String strResponse = null;
        if (response != null) {
            try {
                strResponse = responseHandler.handleResponse(response);
            } catch (HttpResponseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Log.e("AltaVerDemoActivity", "Response: " + strResponse);
    }
}

这篇关于Android HTTPPost 返回错误“不允许的方法".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆