改造:无法为 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 参数。
- 砰,成功了。
我正在使用 Moshi
和 Retrofit
,我的问题是我忘记为 DTO
添加 @JsonSerializable
注释 class 为 @body
.
你应该像这样添加这个注释:
@JsonSerializable
data class RegisterDTO(
@field:Json(name = "device_id") val deviceId: String,
)
在我的例子中,我只是忘记为 Gradle 应用 kotlinx.serialization 插件,因此没有生成序列化程序的代码。通过以下方式修复:
plugins {
kotlin("plugin.serialization")
}
我需要通过改装 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 参数。 - 砰,成功了。
我正在使用 Moshi
和 Retrofit
,我的问题是我忘记为 DTO
添加 @JsonSerializable
注释 class 为 @body
.
你应该像这样添加这个注释:
@JsonSerializable
data class RegisterDTO(
@field:Json(name = "device_id") val deviceId: String,
)
在我的例子中,我只是忘记为 Gradle 应用 kotlinx.serialization 插件,因此没有生成序列化程序的代码。通过以下方式修复:
plugins {
kotlin("plugin.serialization")
}