问题
I need to send a Json to a payment gateway through Retrofit. I really do not know what I have badly tested postman and everything works well. when trying to adapt with retrofit I only get null as a response.
My class Utils
public class ApiUtils {
private ApiUtils() {}
public static final String BASE_URL = "https://api.payulatam.com/";
public static APIService getAPIService() {
return RetrofitClient.getClient(BASE_URL).create(APIService.class);
}
}
My interface Class
public interface APIService {
@Headers({
"Accept: application/json",
"Content-Type: application/json"
})
@POST("payments-api/4.0/service.cgi/")
Call<Ping> sendPing(@Body JsonObject jsonObject);
}
My POJO of the server response.
public class Ping {
@SerializedName("code")
@Expose
private String code;
@SerializedName("error")
@Expose
private Object error;
@SerializedName("transactionResponse")
@Expose
private Object transactionResponse;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Object getError() {
return error;
}
public void setError(Object error) {
this.error = error;
}
public Object getTransactionResponse() {
return transactionResponse;
}
public void setTransactionResponse(Object transactionResponse) {
this.transactionResponse = transactionResponse;
}
}
Main Activities, Ping is the method where I send the Json with the requirements requested by the gateway. I always get an answer null
public class MainActivity extends AppCompatActivity {
private JsonObject SendObj;
private JsonObject objPing;
private TextView mResponseTv;
private APIService mAPIService;
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button submitBtn = (Button) findViewById(R.id.btn_submit);
mAPIService = ApiUtils.getAPIService();
submitBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Ping();
}
});
}
private void Ping(){
JsonObject objMerchant = new JsonObject();
objMerchant.addProperty("apiLogin", "XXXXXXXXXXX");
objMerchant.addProperty("apiKey","XXXXXXXXXXXXXX");
JsonObject objPing = new JsonObject();
objPing.addProperty("test", "false");
objPing.addProperty("language","es");
objPing.addProperty("command","PING");
objPing.add("merchant",objMerchant);
SendPing(objPing);
Log.i(TAG, "Obj" + objPing.toString());
}
public void SendPing(JsonObject body) {
Call <Ping> call = mAPIService.sendPing(body);
call.enqueue(new Callback<Ping>() {
@Override
public void onResponse(Call<Ping> call, Response<Ping> response) {
Log.d(TAG,"Getting response from server : "+ response.body());
}
@Override
public void onFailure(Call<Ping> call, Throwable t) {
Log.d(TAG,"Getting response from server failure: "+ t);
}
});
}
}
postman request
回答1:
You don't need to mention that:
@Headers({
"Accept: application/json",
"Content-Type: application/json"
})
So remove this from your code.
test is boolean in your postman request but here you are passing as string so change following:
JsonObject objMerchant = new JsonObject();
objMerchant.addProperty("apiLogin", "XXXXXXXXXXX");
objMerchant.addProperty("apiKey","XXXXXXXXXXXXXX");
JsonObject objPing = new JsonObject();
objPing.addProperty("test", "false");
objPing.addProperty("language","es");
objPing.addProperty("command","PING");
objPing.add("merchant",objMerchant);
to:
JsonObject objMerchant = new JsonObject();
objMerchant.addProperty("apiLogin", "XXXXXXXXXXX");
objMerchant.addProperty("apiKey","XXXXXXXXXXXXXX");
JsonObject objPing = new JsonObject();
objPing.addProperty("test", false);
objPing.addProperty("language","es");
objPing.addProperty("command","PING");
objPing.add("merchant",objMerchant);
Test attribute is boolean in your postman request but here you were passing as string.
回答2:
Why there's no endpoint in @POST("./")?
Basically BASE_URL should be https://api.payulatam.com/ and your POST endpoint should be
@POST("payments-api/4.0/service.cgi/")
Besides, why are you creating request body manually? You can use a POJO class to serialize the request and I think it will be easier to handle that way. For example,
public class Request{
@SerializedName("language")
public String language; //you can use private as well
}
and to create the request,
Request request = new Request();
request.language = "es";
So in your interface, put it this way:
Call<Ping> sendPing(@Body Request request);
Can you try this and see?
Updated request object from postman request:
public class Request {@SerializedName("test")
public boolean test;
@SerializedName("language")
public String language;
@SerializedName("command")
public String command;
@SerializedName("merchant")
public Merchant merchant;
public class Merchant{
@SerializedName("apiLogin")
public String apiLogin;
@SerializedName("apiKey")
public String apiKey;
}
}
来源:https://stackoverflow.com/questions/50027472/retrofit-sending-json