改造调用返回 400,cURL 请求工作正常,语法问题



我尝试对 API 端点进行改造调用,但它返回了一个400 error,但是我的 curl 请求工作正常。我似乎无法发现错误,有人可以仔细检查我的工作以查看我犯错的地方吗?

有效的卷曲调用:

curl --request POST https://connect.squareupsandbox.com/v2/payments 
--header "Content-Type: application/json" 
--header "Authorization: Bearer accesstoken112233" 
--header "Accept: application/json" 
--data '{
"idempotency_key": "ab2a118d-53e2-47c6-88e2-8c48cb09bf9b",
"amount_money": {
"amount": 100,
"currency": "USD"},
"source_id": "cnon:CBASEITjGLBON1y5od2lsdxSPxQ"}'

我的改造电话:

public interface IMakePayment {
@Headers({
"Accept: application/json",
"Content-Type: application/json",
"Authorization: Bearer accesstoken112233"
})
@POST(".")
Call<Void> listRepos(@Body DataDto dataDto);
}

DataDto 类:

public class DataDto {
private String idempotency_key;
private String amount_money;
private String source_id;
public DataDto(String idempotency_key, String amount_money, String source_id) {
this.idempotency_key = idempotency_key;
this.amount_money = amount_money;
this.source_id = source_id;
}
}

最后进行改造:

DataDto dataDto = new DataDto("ab2a118d-53e2-47c6-88e2-8c48cb09bf9b", "{"amount": 100, "currency": "USD"}", "cnon:CBASEITjGLBON1y5od2lsdxSPxQ");
RetrofitInterfaces.IMakePayment service = RetrofitClientInstance.getRetrofitInstance().create(RetrofitInterfaces.IMakePayment.class);
Call<Void> call = service.listRepos(dataDto);
call.enqueue(new Callback<Void>() {
@Override
public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
Log.d(TAG, "onResponse: " + response.toString());
}
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Log.d(TAG, "onFailure: Error: " + t);
}
});

改造实例:

public class RetrofitClientInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "https://connect.squareupsandbox.com/v2/payments/";

public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}

编辑 1:将第二个参数更改为 JSON 对象

JSONObject jsonObject = new JSONObject();
try{
jsonObject.put("amount", 100);
jsonObject.put("currency", "USD");
}catch (Exception e){
Log.d(TAG, "onCreate: " + e);
}
DataDto dataDto = new DataDto("ab2a118d-53e2-47c6-88e2-8c48cb09bf9b", jsonObject, "cnon:CBASEITjGLBON1y5od2lsdxSPxQ");

首先,让我们看看400是什么意思

超文本传输协议 (HTTP( 400 错误请求响应状态 代码指示服务器无法或不会处理请求 由于被认为是客户端错误(例如, 请求语法格式不正确、请求消息帧无效或 欺骗性请求路由(。

现在我们确定,问题出在我们的请求中(不是服务器故障(,很可能是因为您正在尝试在请求中转换 JSON(不要明确执行此操作 GSON 将自动转换(

使用拦截器验证您的传出网络请求(在此处告知结果(

您使用@POST("."(没有意义,请理解BASE_URL是您的服务器URL而不是更多

问题可能是翻译此帖子请求

所以一个可能的解决方案

  • 将基本网址更改为"https://connect.squareupsandbox.com/"
  • @POST(".")替换为@POST("v2/payments/")

@NaveenNiraula提到正确的事情,即使它没有帮助您,请按照他的指示进行操作,这是使用 GSON 解析数据的正确方法(确保您包含它并正确配置它(转换器

编辑

我让它工作(我消除了 400 个错误代码,只要涉及问题标题,这就是您想要的(,这意味着我检测到发生 400 错误的原因并修复了它,但不幸的是,我卡住了未经授权的问题。问题与转换 json 和数据类型有关

data class DataDTO(
val idempotency_key: String,
val source_id: String,
val amount_money: MoneyAmount
)
data class MoneyAmount(
val amount: Int,
val currency: String
)

我在这里概括了您可以参考的所有代码

你需要两个DTO类,如下所示:

public class Amount_money
{
private String amount;
private String currency;
public String getAmount ()
{
return amount;
}
public void setAmount (String amount)
{
this.amount = amount;
}
public String getCurrency ()
{
return currency;
}
public void setCurrency (String currency)
{
this.currency = currency;
}
@Override
public String toString()
{
return "ClassPojo [amount = "+amount+", currency = "+currency+"]";
}
}

public class DataDto
{
private String idempotency_key;
private Amount_money amount_money;
private String source_id;
public String getIdempotency_key ()
{
return idempotency_key;
}
public void setIdempotency_key (String idempotency_key)
{
this.idempotency_key = idempotency_key;
}
public Amount_money getAmount_money ()
{
return amount_money;
}
public void setAmount_money (Amount_money amount_money)
{
this.amount_money = amount_money;
}
public String getSource_id ()
{
return source_id;
}
public void setSource_id (String source_id)
{
this.source_id = source_id;
}
@Override
public String toString()
{
return "ClassPojo [idempotency_key = "+idempotency_key+", amount_money = "+amount_money+", source_id = "+source_id+"]";
}
}

您需要为每个对象创建对象,例如:

Amount_money am = new Amount_money();
am.setAmount("100");
am.setCurrency("USD");
DataDto dto = new DataDto();
dto.setIdempotency_key("your key");
dto.setsource_id("your id");
dto.setAmount_money(am);
RetrofitInterfaces.IMakePayment service = RetrofitClientInstance.getRetrofitInstance().create(RetrofitInterfaces.IMakePayment.class);
Call<Void> call = service.listRepos(dataDto);
// yo get the point follow along

传递的 JSON 结构很可能没有以相同的格式序列化。

"amount_money": {
"amount": 100,
"currency": "USD"},

我首先会使用具有amountcurrency字段的真正DTOprivate String amount_money;。这应该会取得进展。我不是 100% 确定属性的下划线映射是什么样子的,但这是下一步。

添加日志记录以便能够查看传递的数据。快速搜索显示本教程:https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses。在查看传输的数据时,应该很容易比较预期数据和发送的数据。

请检查您的基本网址。

在你的卷发中,你有https://connect.squareupsandbox.com/v2/payments

但是在你拥有的代码中

private static final String BASE_URL = "https://connect.squareupsandbox.com/v2/payments/";

最后还有额外的/(斜杠(。我见过这是问题所在的情况。可能是你的问题:)

最新更新