【问题标题】:Send Post Request with params using Retrofit使用 Retrofit 发送带有参数的 Post 请求
【发布时间】: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&lt;LandingPageReport&gt;。但是现在出现这个错误

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&amp;Code这部分可能无效
  • 你的意思是什么?我该怎么做?在 iOS 上工作,我所做的就是将此字符串“par1=adads&par2=asd”转换为 NSDATA 并将其放入请求中。
  • symbol &amp; 就像请求参数的分隔符,所以你应该将你的 API 方法(在你的 API 中)重命名为 GetDetailWithMonthAndCode
  • 我已经更新了帖子。先生,当我在这里写帖子时,这只是一个错误。
  • 错误可能出在您的 API 中。另外,您应该使用GET http 方法来获取数据,而不是POST

标签: android post retrofit


【解决方案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_width="wrap_content"
              android:layout_height="match_parent"
              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_width="200dp"
                      android:layout_height="150dp"
                      android:layout_gravity="center"
                      android:layout_marginTop="20dp"
                      android:padding="5dp"
                      android:background="@mipmap/ic_launcher_round"
                      />
      
                  <TextView
                      android:id="@+id/txtLogo"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      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_width="fill_parent"
                      android:layout_height="wrap_content"
                      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_width="fill_parent"
                          android:layout_height="wrap_content"
                          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_width="fill_parent"
                      android:layout_height="wrap_content"
                      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_width="match_parent"
                          android:layout_height="wrap_content"
                          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_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_below="@+id/textInputLayout2"
                      android:layout_marginTop="10dp"
                      android:layout_marginLeft="10dp"
                      >
      
                      <Button
                          android:id="@+id/loginSub"
                          android:layout_width="wrap_content"
                          android:layout_height="45dp"
                          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>
      

      【讨论】:

      【解决方案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;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-12-04
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 2017-02-02
        • 2018-04-13
        • 2020-04-06
        • 2019-10-09
        • 2020-11-18
        相关资源
        最近更新 更多