改造:无法为 class 创建 @Body 转换器

Retrofit: Unable to create @Body converter for class

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

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

与Header: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 参数。它适合我

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 而不是 class。

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

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

解法: 在您的界面中使用 next 声明 body 值:

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

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

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

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

您有可能为多个 vairable/fields/tags

保留相同的 @SerializedName("")

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

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

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

但是,这是正确的:

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

当我 升级到 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 参数。
  • 砰,成功了。

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

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

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

plugins {
    kotlin("plugin.serialization")
}