2015-12-14 262 views
2

我正在使用Retrofit 2.0.0將POST請求發送到我的REST API。發送POST請求時無法獲取POST參數,請使用Retrofit

private class AuthTask extends AsyncTask<String, String, String> { 
    protected String doInBackground(String... params) { 
     Call<Auth> call = service.auth(params[0], params[1]); 
     try { 
      Auth authResponse = call.execute().body(); 
      Log.i(AuthActivity.class.getName(), authResponse.public_key); 
     } catch (IOException ex) { 
      Log.e(AuthActivity.class.getName(), "Error."); 
      return "error"; 
     } 
     return "success"; 
    } 

    protected void onPostExecute(String result) { 
     Log.i(AuthTask.class.getName(), "Done"); 
    } 
} 

public class Auth { 
    public String public_key; 
} 

public interface AuthService { 
    @FormUrlEncoded 
    @POST("auth") 
    Call<Auth> auth(@Field("username") String username, @Field("publickey") String publickey); 
} 

這裏是我的請求日誌輸出:

12-14 19:36:54.014 30318-30373/com.app D/OkHttp: --> POST /auth HTTP/1.1 
12-14 19:36:54.014 30318-30373/com.app D/OkHttp: username=ghtbznz&publickey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCedhOhP9MgYufDxPKH1DdtJiBBdBtbsUy8R7kg%0AWm1Edm7c3ThToMxMgjvOAsHn8rP1Ka1eVN34hC4HV2%2BoomRaWH25WbunN9ZVRqBnowsTOd40eEKh%0A6dsO8Cl3u65VsArDyZyEQa7Ofx29i2juOpWRG%2F6tp9FVnJzZt5dBDkWOKwIDAQAB%0A 
12-14 19:36:54.014 30318-30373/com.app D/OkHttp: --> END POST (256-byte body) 

這裏是爲響應日誌輸出:

12-14 19:42:20.358 2549-2804/com.app D/OkHttp: <-- HTTP/1.1 200 OK (1790ms) 
12-14 19:42:20.358 2549-2804/com.app D/OkHttp: Date: Mon, 14 Dec 2015 18:42:16 GMT 
12-14 19:42:20.358 2549-2804/com.app D/OkHttp: Server: Apache/2.2.22 (Debian) 
12-14 19:42:20.358 2549-2804/com.app D/OkHttp: Vary: Accept-Encoding 
12-14 19:42:20.358 2549-2804/com.app D/OkHttp: Keep-Alive: timeout=5, max=99 
12-14 19:42:20.366 2549-2804/com.app D/OkHttp: Connection: Keep-Alive 
12-14 19:42:20.366 2549-2804/com.app D/OkHttp: Content-Type: text/html 
12-14 19:42:20.366 2549-2804/com.app D/OkHttp: OkHttp-Selected-Protocol: http/1.1 
12-14 19:42:20.366 2549-2804/com.app D/OkHttp: OkHttp-Sent-Millis: 1450118540088 
12-14 19:42:20.366 2549-2804/com.app D/OkHttp: OkHttp-Received-Millis: 1450118540358 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: array(0) { 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: } 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: Notice: Undefined index: username in /home/auth/index.php on line 45 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: Notice: Undefined index: publickey in /home/auth/index.php on line 46 
12-14 19:42:20.373 2549-2804/com.app D/OkHttp: <-- END HTTP (251-byte body) 

在我的PHP文件,這是我找回POST參數:

$user = $_POST["username"]; 
$pk = $_POST["publickey"]; 

奇怪的是,當我使用curl發送POST請求一切正常。所以我的問題是爲什麼我無法使用Retrofit發送正確的POST參數?

回答

1

我在我的Android手機上安裝了應用程序鯊魚,並嗅探了流量。最後,我發現發生了重定向(301),因此所有POST參數都消失了。

解決方案非常簡單。只需在REST端點之後添加斜線即可:

public interface AuthService { 
    @FormUrlEncoded 
    @POST("auth/") 
    Call<Auth> auth(@Field("username") String username, @Field("publickey") String publickey); 
} 
1

改裝可能類似於Angular,因爲數據作爲MIME類型「application/json」而不是「application/x-www-form-urlencoded」或「multipart/form-data」發佈。如果它是「application/json」,PHP將不會將數據解析到$ _POST中。所以,你必須做你自己。我做這樣的事情...

if (isset($_SERVER['CONTENT_TYPE']) 
    and stripos($_SERVER['CONTENT_TYPE'], 'application/json') !== false 
) { 
    $jsonEncoded = file_get_contents('php://input'); 
    $jsonDecoded = json_decode($jsonEncoded, true); 
    if (is_array($jsonDecoded)) { 
     foreach ($jsonDecoded as $varName => $varValue) { 
      $_POST[$varName] = $varValue; 
     } 
    } 
} 
+0

謝謝您的幫助。不幸的是,這並沒有解決問題。我想我正在發送'application/x-www-form-urlencoded',因爲註釋是@ FormUrlEncoded。 – user3475602

+0

奇怪的是,當我使用curl時,我得到'application/x-www-form-urlencoded',但是當我通過Retrofit發送請求時,我得到了'Notice:Undefined index:CONTENT_TYPE'。 – user3475602

+0

嗯,看起來像Retrofit可能不會發送一個「內容類型」的HTTP頭...所以PHP是說跆拳道,我沒有做不解析。你可以嘗試去掉if(...)來繞過我上面的代碼,強制PHP試圖總是讀取/解析原始輸入。如果json_decode不能解析,它不會返回一個數組,所以is_array測試可以防止崩潰。 – BareNakedCoder