如何在 Android 中使用 Retrofit 发送 JSON POST 请求,并接收字符串响应

Posted

技术标签:

【中文标题】如何在 Android 中使用 Retrofit 发送 JSON POST 请求,并接收字符串响应【英文标题】:How to send a JSON POST request using Retrofit in Android, and recieve a String response 【发布时间】:2019-02-06 05:14:24 【问题描述】:

我是第一次使用 Retrofit2,遇到了一些问题。

这是用于调用 REST API 的代码 sn-p

    //building retrofit object
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://192.168.0.71:9000/api/uniapp/")
            .addConverterFactory(GsonConverterFactory.create())
            .addConverterFactory(ScalarsConverterFactory.create())
            .build();

    APIService service = retrofit.create(APIService.class);

    //defining the call
    Call<String> call = service.refreshAppMetaConfig("0");
    //calling the api
    call.enqueue(new Callback<String>() 
        @Override
        public void onResponse(Call<String> call, Response<String> response) 
            //displaying the message from the response as toast
            System.out.println("Uniapp :"+response);
        

        @Override
        public void onFailure(Call<String> call, Throwable t) 
            System.out.println("Uniapp :"+t.getMessage());
        
    );

这是 APIService 类:

public interface APIService 

    //The register call
    @FormUrlEncoded
    @POST("appmetaconfigjson")
    Call<String> refreshAppMetaConfig(@Field("versionId") String versionId);

我正在使用 Play 框架来创建 REST API。我收到内部服务器错误。 API 无法读取 JSON 请求。但是如果我通过 Postman 访问 API,它会返回响应。有什么建议吗?

我添加了邮递员请求截图。

【问题讨论】:

How to POST raw whole JSON in the body of a Retrofit request?的可能重复 也许你需要设置标题? 我们如何设置标题? 尝试将此添加到您的 ApiService @Headers("Content-Type: application/x-www-form-urlencoded") 还要仔细检查您的 url 端点和参数可能有问题 【参考方案1】:

从 Postman 的屏幕截图中可以看出,您正在将 JSON 正文发送到 REST API。当你在 Postman 中选择 body type 为raw - application/json 时,它会自动包含

Content-Type:application/json

作为标题。因此,请求在 Postman 中是成功的。

现在,为了使其在您的 android 应用程序中成功运行上述请求,您需要为发送到 REST API 的请求设置标头。

APIService界面中进行以下更改。

import retrofit2.http.Body;
import okhttp3.ResponseBody;
import java.util.Map;


public interface APIService 

  //The register call
  // @FormUrlEncoded    <====  comment or remove this line

   @Headers(
        "Content-Type:application/json"
   )
   @POST("appmetaconfigjson")
   Call<ResponseBody> refreshAppMetaConfig(@Body Map<String, String> versionId);

    删除或评论 @FormUrlEncoded 注释,因为我们发送的是 JSON 而不是 FormUrlEncoded 数据。 用Content-Type:application/json添加@Headers()注解 将方法参数更改为@Body Map&lt;String, String&gt; versionId。当您向 API 请求时,@Body 注释将Map (HashMap) 数据转换(序列化)为 JSON 正文。 将返回参数从String更改为ResponseBody

使用上面修改的方法如下

// code...

//defining the call

// create parameter with HashMap
Map<String, String> params = new HashMap<>();
params.put("versionId", "0");

Call<ResponseBody> call = service.refreshAppMetaConfig(params);
//calling the api
call.enqueue(new Callback<ResponseBody>() 
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) 
        //displaying the message from the response as toast

        // convert ResponseBody data to String
        String data = response.body().string();

        System.out.println("Uniapp : " + data);
    

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) 
        System.out.println("Uniapp : " + t.getMessage());
    
);

这里您还需要将参数从Call&lt;String&gt; 更改为Call&lt;ResponseBody&gt;。并使用response.body().string(); 转换onResponse() 方法内的响应。

【讨论】:

请正确检查答案中使用的方法名称、导入和参数,如果有任何混淆,请复制粘贴代码。

以上是关于如何在 Android 中使用 Retrofit 发送 JSON POST 请求,并接收字符串响应的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Retrofit 在 android 中调用图像上传 Web 服务 (ASP.NET) .asmx 文件

如何使用 Retrofit Android Kotlin 发布 [重复]

如何在Android上通过retrofit2调用带有Cognito Credentials的API网关?

深度详解Retrofit2使用实践

深度详解Retrofit2使用实践

如何将 AsyncTask 转换为 Retrofit 以从 Android 中的 WCF Webservice 获取数据