使用改造

时间:2015-05-12 02:54:55

标签: android post retrofit

我尝试使用Retrofit库在Android上使用API​​时失败,但在使用POSTMAN时我可以看到预期的结果。

POSTMAN SETTING

  • api url(base + controller)

  • HTTP方法设置为POST

  • 点击了from-data或x-www-form-urlencoded

  • 然后我在键/值字段上传递两个参数。

ANDROID RETROFIT SETTING

@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",
     }
   ]
}

但我仍无法解析回复。

6 个答案:

答案 0 :(得分:26)

的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:paddingLeft="@dimen/edit_input_padding"
                    android:paddingRight="@dimen/edit_input_padding"
                    android:paddingTop="@dimen/edit_input_padding"
                    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>

答案 1 :(得分:20)

这是一个简单的解决方案,我们不需要使用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

答案 2 :(得分:14)

我找到了解决方案。这个问题在我的课程结构中是一个问题。所以我像下面的样本一样更新它们。

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);

答案 3 :(得分:2)

您应该为此创建一个界面,

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

答案 4 :(得分:1)

我认为好的方法是将其发送到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));

答案 5 :(得分:1)

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

}