【问题标题】:Retrofit: Unable to create @Body converter for class改造:无法为类创建@Body 转换器
【发布时间】:2016-06-23 04:43:54
【问题描述】:

我需要通过改造 2 发送下一个 json:

{
    "Inspection": {
        "UUID": "name",
        "ModifiedTime": "2016-03-09T01:13",
        "CreatedTime": "2016-03-09T01:13",
        "ReviewedWith": "name2",
        "Type": 1,
        "Project": {
            "Id": 41
        },
        "ActionTypes": [1]
    }   
}

带标题:Authorization: access_token_value

我试过这个:

//header parameter
String accessToken = Requests.getAccessToken();

JsonObject obj = new JsonObject();
JsonObject inspection = new JsonObject();

inspection.addProperty("UUID","name");
inspection.addProperty("ModifiedTime","2016-03-09T01:13");
inspection.addProperty("CreatedTime","2016-03-09T01:13");
inspection.addProperty("ReviewedWith","name2");
inspection.addProperty("Type","1");

JsonObject project = new JsonObject();
project.addProperty("Id", 41);

inspection.add("Project", project);
obj.add("Inspection", inspection);

Retrofit restAdapter = new Retrofit.Builder()
        .baseUrl(Constants.ROOT_API_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .addConverterFactory(ScalarsConverterFactory.create())
        .build();
IConstructSecureAPI service = restAdapter.create(IConstructSecureAPI.class);
Call<JsonElement> result = service.addInspection(accessToken, obj);
JsonElement element = result.execute().body();

但每次我收到异常:java.lang.IllegalArgumentException: Unable to create @Body converter for class com.google.gson.JsonObject (parameter #2)

如何发送?或者任何其他想法我该怎么做。您甚至可以为我提供简单的String 参数,其中包含 json。很适合我

【问题讨论】:

  • 请发布 IConstructSecureAPI 以了解您如何构建您的请求。

标签: java json retrofit retrofit2


【解决方案1】:

解决方案: 在你的界面中用 next 声明 body 值:

@Body RequestBody body 并包装字符串 JSON 对象:

RequestBody body = RequestBody.create(MediaType.parse("application/json"), obj.toString());

【讨论】:

  • 用这个解决方案解决了问题。非常感谢!
【解决方案2】:

您有可能为多个变量/字段/标签保留相同的 @SerializedName("")

【讨论】:

  • 哈!这是我的问题。不错的建议。
  • 哇,谢谢!我希望错误信息更清楚
【解决方案3】:

你可以像这样创建改造时指定一个转换器

Retrofit retrofit = new Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(baseurl)
        .client(okHttpClient)
        .build();

【讨论】:

    【解决方案4】:

    Body 使用单个请求对象,声明您的请求对象如下

    class Inspection {
        String UUID;
        //..... add your fields 
        Project project;      
    }
    
    class Product
    {
       int Id;
       //....... add your fields 
    }
    

    我假设您的服务IConstructSecureAPI 端点是:

    @GET(...)    // change based on your api GET/POST
    Call<Response> addInspection(
        @Header("Authorization") String accesstoken, 
        @Body Inspection request
    );
    

    你可以在Response宣布你的愿望。

    检查这个answer,它使用HashMap 而不是类。

    【讨论】:

    • 你的答案是正确的,但我忘了写 ".addConverterFactory(GsonConverterFactory.create())" =)
    【解决方案5】:

    如果这是由于@SerializedName 造成的,请确保它没有重复。

    例如以下情况会抛出此错误:(注意:bookingId 被传递两次)

    @SerializedName(value="bookingId", alternate={"id", "bookingId"})
    

    但是,这是正确的:

    @SerializedName(value="bookingId", alternate={"id", "someOtherId", "whateverId"})
    

    【讨论】:

      【解决方案6】:

      您可以使用拦截器在每个请求中发送授权标头

      class AuthorizationInterceptor implements Interceptor {
      
          @Override
          public Response intercept(Chain chain) throws IOException {
              Request originalRequest = chain.request();
              String authorizationToken = AuthenticationUtils.getToken();
              Request authorizedRequest = originalRequest.newBuilder()
                  .header("Authorization", authorizationToken)
                  .build();
              return chain.proceed(authorizedRequest);
          }
      }
      

      【讨论】:

        【解决方案7】:

        当我升级到 Java 17 时,我一直收到此错误,但在 Java 11 上仍然可以正常工作。

        这对我有用

        • 为了深入了解异常,我在改造堆栈跟踪中找到的 Utils.java 中放置了一个调试点。
        • 这样做导致我更狭窄的原因是:java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte java.time.LocalTime.hour accessible: module java.base does not "opens java.time" to unnamed module @35e2d654
        • 从这里进一步向下搜索导致我找到https://github.com/mockk/mockk/issues/681#issuecomment-959646598,简而言之,它建议将--add-opens java.base/java.time=ALL-UNNAMED 添加为 JVM 参数。
        • 砰,它奏效了。

        【讨论】:

          【解决方案8】:

          我正在使用MoshiRetrofit,我的问题是我忘记为DTO 类为@body 添加@JsonSerializable 注释。 你应该像这样添加这个注释:

          @JsonSerializable
          data class RegisterDTO(
              @field:Json(name = "device_id") val deviceId: String,
          )
          

          【讨论】:

            【解决方案9】:

            就我而言,我只是忘记为 Gradle 应用 kotlinx.serialization 插件,因此没有生成序列化程序的代码。通过以下方式修复它:

            plugins {
                kotlin("plugin.serialization")
            }
            

            【讨论】:

              猜你喜欢
              • 2021-05-13
              • 2019-07-25
              • 2021-11-22
              • 2021-06-12
              • 1970-01-01
              • 2020-03-12
              • 2018-10-19
              • 2017-01-12
              • 1970-01-01
              相关资源
              最近更新 更多