2011-06-07 78 views
2

我正在編寫Android 2.2應用程序,將json嚴格性發布到ReSTfull Web服務。Android HTTPPost返回錯誤「方法不允許」。

提琴手調用與相同的Json返回Web服務預期,並且具有相同的Json返回預期一個aspx的Web應用程序。

當我看到服務器日誌,我可以看到服務器響應初始POST動詞用307重定向,然後立即一個GET和405錯誤。

提琴手和ASPX應用程序日誌有307重定向POST,然後立即另一個POST和200確定。

這是怎麼回事?

這是主要活動:

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 
    } 
} 

這是類代碼做Web服務調用:

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>\n"+jsonObjRecv.toString()+"\n</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 + "\n"); 
      } 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } finally { 
      try { 
      is.close(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
      } 
      return sb.toString(); 
    } 
} 

回答

11

在網址的結尾放置一個「/」導致重定向發生因爲您的服務器喜歡以'/'結尾的網址。 POST完全由您的服務器重定向到的URL支持,但客戶端在根據您的setRedirecting()調用行爲時執行GET請求(cURL與-L切換器完全相同)修復方法是將put在URL末尾加一個'/',或者自己從響應中獲取位置標題,然後手動啓動另一個POST請求。

這可以在wireshark中觀察到。您可以通過嘗試使用瀏覽器對URL執行GET請求來測試理論,其中附有斜線。這將導致瀏覽器獲得405下面是Android上的固定代碼,該代碼使用附加的「/」的簡單修復的URL(未投入生產):

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); 
    } 
} 
+0

非常感謝您的幫助,湯姆。這是正確的答案。 – 2011-07-07 00:47:41

+0

@Stuart,你距離毫米。你給了我一個很大的問題。 – 2011-07-07 01:17:11

+0

偉大的工作真的可以節省我很多時間,謝謝。 – 2012-05-21 13:58:26

1

上述問題經常發生如果服務中的請求類型是WebGet,例如

WebGet(UriTemplate = "login/?name={name}&password={password}", ResponseFormat = WebMessageFormat.Json)" 

並且您嘗試通過android訪問使用HttpPost的方法。

我有同樣的問題,我花了小時才能弄清楚。

2

我看了上面的答案,似乎有點太複雜!

我所做的一切爲了解決這個(這正如一些答案國家中,由於不允許職位的服務),是改變:

HttpPost post = new HttpPost(params[0]); 
HttpResponse response = client.execute(post); 

對於

HttpGet get = new HttpGet(params[0]); 
HttpResponse response = client.execute(get); 

而且解決了它!

PD:我正在狀態代碼:405!

+0

這是解決了我的問題,謝謝。 – bebosh 2015-01-27 01:16:52

相關問題