使用 Retrofit 发送带有参数的 Post 请求
Posted
技术标签:
【中文标题】使用 Retrofit 发送带有参数的 Post 请求【英文标题】:Send Post Request with params using Retrofit 【发布时间】:2015-07-22 17:48:09 【问题描述】:我尝试使用 Retrofit 库在 android 上使用 API 未成功,但在使用 POSTMAN 时,我可以看到预期的结果。
邮递员设置
api url (base+controller)
HTTP 方法设置为 POST
点击了 from-data 或 x-www-form-urlencoded
然后我在键/值字段上传递两个参数。
安卓改造设置
@POST("/GetDetailWithMonthWithCode")
void getLandingPageReport(@Query("code") String code,
@Query("monthact") String monthact,
Callback<LandingPageReport> cb);
@FormUrlEncoded
@POST("/GetDetailWithMonthWithCode")
void getLandingPageReport(@Field("code") String code,
@Field("monthact") String monthact,
Callback<LandingPageReport> cb);
这些选项都不起作用。但结果是 。
更新
使用标准HttpClient
(和HttpPost
)类的相同设置可以正常工作。
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("code", "testcode"));
urlParameters.add(new BasicNameValuePair("monthact", "feb-2015"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
为什么我不能执行这个请求并在 Retrofit 中得到正确的响应?
更新 2
@POST("/GetDetailWithMonthWithCode")
void getLandingPageReport(@Query("code") String code,
@Query("monthact") String monthact,
Callback<List<LandingPageReport>> cb);
@FormUrlEncoded
@POST("/GetDetailWithMonthWithCode")
void getLandingPageReport(@Field("code") String code,
@Field("monthact") String monthact,
Callback<List<LandingPageReport>>> cb);
玩了一圈之后,我想我找到了问题的根源。我已更新我的改造代码以接收List<LandingPageReport>
。但是现在出现这个错误
retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:应为 BEGIN_ARRAY,但为 BEGIN_OBJECT 在第 1 行第 2 列路径 $
原因是我消耗了 2 个 api(webapi 和 wcf)。我所有的其他json
响应都是对象数组。 [,] 但在这次通话中我收到了这个
"GetDetailWithMonthWithCodeResult": [
"code": "test",
"field1": "test",
]
但我仍然无法解析响应。
【问题讨论】:
GetDetailWithMonth&Code
这部分可能无效
你的意思是什么?我该怎么做?在 ios 上工作,我所做的就是将此字符串“par1=adads&par2=asd”转换为 NSDATA 并将其放入请求中。
symbol &
就像请求参数的分隔符,所以你应该将你的 API 方法(在你的 API 中)重命名为 GetDetailWithMonthAndCode
我已经更新了帖子。先生,当我在这里写帖子时,这只是一个错误。
错误可能出在您的 API 中。另外,您应该使用GET
http 方法来获取数据,而不是POST
。
【参考方案1】:
我找到了解决方案。这个问题是我的班级结构中的一个问题。所以我像下面的示例一样更新了它们。
public class LandingPageReport
private ArrayList<LandingPageReportItem> GetDetailWithMonthWithCodeResult;
// + Getter Setter methods
public class LandingPageReportItem
private String code;
private String field1;
// + Getter Setter methods
然后我使用这个改造配置
@POST("/GetDetailWithMonthWithCode")
void getLandingPageReport(@Field("code") String code,
@Field("monthact") String monthact,
Callback<LandingPageReport> cb);
【讨论】:
【参考方案2】:这是一个简单的解决方案,我们不需要使用 JSON
public interface RegisterAPI
@FormUrlEncoded
@POST("/RetrofitExample/insert.php")
public void insertUser(
@Field("name") String name,
@Field("username") String username,
@Field("password") String password,
@Field("email") String email,
Callback<Response> callback);
发送数据的方法
private void insertUser()
//Here we will handle the http request to insert user to mysql db
//Creating a RestAdapter
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(ROOT_URL) //Setting the Root URL
.build(); //Finally building the adapter
//Creating object for our interface
RegisterAPI api = adapter.create(RegisterAPI.class);
//Defining the method insertuser of our interface
api.insertUser(
//Passing the values by getting it from editTexts
editTextName.getText().toString(),
editTextUsername.getText().toString(),
editTextPassword.getText().toString(),
editTextEmail.getText().toString(),
//Creating an anonymous callback
new Callback<Response>()
@Override
public void success(Response result, Response response)
//On success we will read the server's output using bufferedreader
//Creating a bufferedreader object
BufferedReader reader = null;
//An string to store output from the server
String output = "";
try
//Initializing buffered reader
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
//Reading the output in the string
output = reader.readLine();
catch (IOException e)
e.printStackTrace();
//Displaying the output as a toast
Toast.makeText(MainActivity.this, output, Toast.LENGTH_LONG).show();
@Override
public void failure(RetrofitError error)
//If any error occured displaying the error as toast
Toast.makeText(MainActivity.this, error.toString(),Toast.LENGTH_LONG).show();
);
现在我们可以使用 php aur 任何其他服务器端脚本来获取发布请求。
来源Android Retrofit Tutorial
【讨论】:
只是从源评论中复制,cz 我遇到了问题,RestAdapter doesnt get resolved please help me out
..【参考方案3】:
我认为最好的方法是将其发送到POST Body
,这意味着您将创建一个新的 POJO,但有些人可能最喜欢这个实现。
public interface APIInterface
@POST("/GetDetailWithMonthWithCode")
List<LandingPageReport> getLandingPageReport(@Body Report report);
然后使用构造函数、getter 和 setter 来制作你的 POJO。
public static class Report
private String code;
private String monthact;
public Report(String code, String monthact)
this.code = code;
this.monthact = monthact;
// Getters and Setters...
就用正常的方式来称呼它。
Call<List<Report>> request = apiInterface
.createRetrofitAPIInterface()
.getLandingPageReport(new Report(code, monthact));
【讨论】:
【参考方案4】:build.gradle
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.1.0'// compulsory
compile 'com.squareup.retrofit2:converter-gson:2.1.0' //for retrofit conversion
登录API放两个参数
"UserId": "1234",
"Password":"1234"
登录响应
"UserId": "1234",
"FirstName": "Keshav",
"LastName": "Gera",
"ProfilePicture": "312.113.221.1/GEOMVCAPI/Files/1.500534651736E12p.jpg"
APIClient.java
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
class APIClient
public static final String BASE_URL = "Your Base Url ";
private static Retrofit retrofit = null;
public static Retrofit getClient()
if (retrofit == null)
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
APIInterface接口
interface APIInterface
@POST("LoginController/Login")
Call<LoginResponse> createUser(@Body LoginResponse login);
登录Pojo
package pojos;
import com.google.gson.annotations.SerializedName;
public class LoginResponse
@SerializedName("UserId")
public String UserId;
@SerializedName("FirstName")
public String FirstName;
@SerializedName("LastName")
public String LastName;
@SerializedName("ProfilePicture")
public String ProfilePicture;
@SerializedName("Password")
public String Password;
@SerializedName("ResponseCode")
public String ResponseCode;
@SerializedName("ResponseMessage")
public String ResponseMessage;
public LoginResponse(String UserId, String Password)
this.UserId = UserId;
this.Password = Password;
public String getUserId()
return UserId;
public String getFirstName()
return FirstName;
public String getLastName()
return LastName;
public String getProfilePicture()
return ProfilePicture;
public String getResponseCode()
return ResponseCode;
public String getResponseMessage()
return ResponseMessage;
MainActivity
package com.keshav.retrofitloginexampleworkingkeshav;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import pojos.LoginResponse;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import utilites.CommonMethod;
public class MainActivity extends AppCompatActivity
TextView responseText;
APIInterface apiInterface;
Button loginSub;
EditText et_Email;
EditText et_Pass;
private Dialog mDialog;
String userId;
String password;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = APIClient.getClient().create(APIInterface.class);
loginSub = (Button) findViewById(R.id.loginSub);
et_Email = (EditText) findViewById(R.id.edtEmail);
et_Pass = (EditText) findViewById(R.id.edtPass);
loginSub.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (checkValidation())
if (CommonMethod.isNetworkAvailable(MainActivity.this))
loginRetrofit2Api(userId, password);
else
CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this);
);
private void loginRetrofit2Api(String userId, String password)
final LoginResponse login = new LoginResponse(userId, password);
Call<LoginResponse> call1 = apiInterface.createUser(login);
call1.enqueue(new Callback<LoginResponse>()
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response)
LoginResponse loginResponse = response.body();
Log.e("keshav", "loginResponse 1 --> " + loginResponse);
if (loginResponse != null)
Log.e("keshav", "getUserId --> " + loginResponse.getUserId());
Log.e("keshav", "getFirstName --> " + loginResponse.getFirstName());
Log.e("keshav", "getLastName --> " + loginResponse.getLastName());
Log.e("keshav", "getProfilePicture --> " + loginResponse.getProfilePicture());
String responseCode = loginResponse.getResponseCode();
Log.e("keshav", "getResponseCode --> " + loginResponse.getResponseCode());
Log.e("keshav", "getResponseMessage --> " + loginResponse.getResponseMessage());
if (responseCode != null && responseCode.equals("404"))
Toast.makeText(MainActivity.this, "Invalid Login Details \n Please try again", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "Welcome " + loginResponse.getFirstName(), Toast.LENGTH_SHORT).show();
@Override
public void onFailure(Call<LoginResponse> call, Throwable t)
Toast.makeText(getApplicationContext(), "onFailure called ", Toast.LENGTH_SHORT).show();
call.cancel();
);
public boolean checkValidation()
userId = et_Email.getText().toString();
password = et_Pass.getText().toString();
Log.e("Keshav", "userId is -> " + userId);
Log.e("Keshav", "password is -> " + password);
if (et_Email.getText().toString().trim().equals(""))
CommonMethod.showAlert("UserId Cannot be left blank", MainActivity.this);
return false;
else if (et_Pass.getText().toString().trim().equals(""))
CommonMethod.showAlert("password Cannot be left blank", MainActivity.this);
return false;
return true;
CommonMethod.java
public class CommonMethod
public static final String DISPLAY_MESSAGE_ACTION =
"com.codecube.broking.gcm";
public static final String EXTRA_MESSAGE = "message";
public static boolean isNetworkAvailable(Context ctx)
ConnectivityManager connectivityManager
= (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
public static void showAlert(String message, Activity context)
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message).setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
);
try
builder.show();
catch (Exception e)
e.printStackTrace();
activity_main.xml
<LinearLayout android:layout_
android:layout_
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/imgLogin"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:padding="5dp"
android:background="@mipmap/ic_launcher_round"
/>
<TextView
android:id="@+id/txtLogo"
android:layout_
android:layout_
android:layout_below="@+id/imgLogin"
android:layout_centerHorizontal="true"
android:text="Holostik Track and Trace"
android:textSize="20dp"
android:visibility="gone" />
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputLayout1"
android:layout_
android:layout_
android:layout_marginLeft="@dimen/box_layout_margin_left"
android:layout_marginRight="@dimen/box_layout_margin_right"
android:layout_marginTop="8dp"
android:padding="@dimen/text_input_padding">
<EditText
android:id="@+id/edtEmail"
android:layout_
android:layout_
android:layout_marginTop="5dp"
android:ems="10"
android:fontFamily="sans-serif"
android:gravity="top"
android:hint="Login ID"
android:maxLines="10"
android:paddingLeft="@dimen/edit_input_padding"
android:paddingRight="@dimen/edit_input_padding"
android:paddingTop="@dimen/edit_input_padding"
android:singleLine="true"></EditText>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputLayout2"
android:layout_
android:layout_
android:layout_below="@+id/textInputLayout1"
android:layout_marginLeft="@dimen/box_layout_margin_left"
android:layout_marginRight="@dimen/box_layout_margin_right"
android:padding="@dimen/text_input_padding">
<EditText
android:id="@+id/edtPass"
android:layout_
android:layout_
android:focusable="true"
android:fontFamily="sans-serif"
android:hint="Password"
android:inputType="textPassword"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<RelativeLayout
android:id="@+id/rel12"
android:layout_
android:layout_
android:layout_below="@+id/textInputLayout2"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
>
<Button
android:id="@+id/loginSub"
android:layout_
android:layout_
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/border_button"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:layout_marginRight="10dp"
android:text="Login"
android:textColor="#ffffff" />
</RelativeLayout>
</LinearLayout>
【讨论】:
谁对布局中的dimen感到困惑..***.com/questions/28005048/… 连接性的一些更新..***.com/questions/32547006/… 在 ApiInterface.java 中定义了方法“createUser”的位置?【参考方案5】:你应该为它创建一个界面,让它运行良好
public interface Service
@FormUrlEncoded
@POST("v1/EmergencyRequirement.php/?op=addPatient")
Call<Result> addPerson(@Field("BloodGroup") String bloodgroup,
@Field("Address") String Address,
@Field("City") String city, @Field("ContactNumber") String contactnumber,
@Field("PatientName") String name,
@Field("Time") String Time, @Field("DonatedBy") String donar);
或者您可以访问http://teachmeandroidhub.blogspot.com/2018/08/post-data-using-retrofit-in-android.html
你可以访问https://github.com/rajkumu12/GetandPostUsingRatrofit
【讨论】:
非常感谢您的分享。这对我有用【参考方案6】:Post data to backend using retrofit
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.okhttp3:logging-interceptor:4.5.0'
public interface UserService
@POST("users/")
Call<UserResponse> userRegistration(@Body UserRegistration
userRegistration);
public class ApiClient
private static Retrofit getRetrofit()
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient
.Builder()
.addInterceptor(httpLoggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.larntech.net/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
return retrofit;
public static UserService getService()
UserService userService = getRetrofit().create(UserService.class);
return userService;
【讨论】:
以上是关于使用 Retrofit 发送带有参数的 Post 请求的主要内容,如果未能解决你的问题,请参考以下文章
使用 Retrofit 发送 POST 请求并接收 Json 响应无法使用响应数据我需要将其传递给另一个活动