2011-06-07 70 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

相关问题