Fra*_*e91 9 android gson retrofit
想象一下以下要求:
@POST("/recipes/create")
void createRecipe(@Query("recipe") Recipe recipe, Callback<String> callback);
Run Code Online (Sandbox Code Playgroud)
我想要json(食谱),但不幸的是我的请求只是调用toString()为我的食谱,它根本不起作用.
我可以覆盖Recipe中的toString,但我宁愿有一个通用的解决方案.
我不能使用@Body,因为我需要指定,我发送的内容(我需要"recipe = json(theRecipe)").
我也无法更改序列化以添加"recipe =",因为我不负责服务器.
目前我正在使用QueryMap Map,我放入了一个序列化对象.虽然这有效,但在我看来,这不是一个非常好的解决方案.
我可以以某种方式拦截改装适配器吗?
Rol*_* W. 10
现在可以在注册Converter.Factory覆盖stringConverter方法的自定义时执行此操作,该自定义在解析参数时调用.@William在2年前提到的Github问题似乎没有更新,因为增加了支持.
方法Javadoc:
返回用于将类型转换为String的Converter,如果此工厂无法处理类型,则返回null.这用于为@Field,@ FieldMap值,@ Header,@ HeaderMap,@ Path,@ Query和@QueryMap值指定的类型创建转换器.
下面的示例委托给Gson,但同样地,任何类型的转换都可以应用于参数.
示例:GsonStringConverterFactory
class GsonStringConverterFactory
extends Converter.Factory {
private final transient Gson gson;
GsonStringConverterFactory(final Gson gson) {
this.gson = gson;
}
@Override
public Converter<?, String> stringConverter(final Type type, final Annotation[] annotations, final Retrofit retrofit) {
final TypeAdapter typeAdapter;
typeAdapter = gson.getAdapter(TypeToken.get(type));
return new StringConverter<>(typeAdapter);
}
private static class StringConverter<T>
implements Converter<T, String> {
private final TypeAdapter<T> typeAdapter;
private StringConverter(final TypeAdapter<T> typeAdapter) {
this.typeAdapter = typeAdapter;
}
@Override
public String convert(final T value)
throws IOException {
/* This works in our case because parameters in this REST api are always some kind of scalar
* and the toJson method converts these to simple json types. */
final String jsonValue;
jsonValue = typeAdapter.toJson(value));
if (jsonValue.startsWith("\"") && jsonValue.endsWith("\"") {
/* Strip enclosing quotes for json String types */
return jsonValue.substring(1, jsonValue.length() - 1);
} else {
return jsonValue;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
注册转换器:
要注册自定义转换器,您的Retrofit构建器可能如下所示:
new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addConverterFactory(new GsonStringConverterFactory(gson))
.build();
Run Code Online (Sandbox Code Playgroud)
我不认为它现在以一种很好的方式支持它.请作者之一检查此答案:https://github.com/square/retrofit/issues/291
该答案建议的方法是创建一个覆盖该toString()方法的自定义类型,因为Retrofit内部用于String.valueOf(value)将查询或路径参数转换为字符串.
所以,你可以这样:
class Recipe {
public int id;
public String title;
@Override
public String toString() {
// You can use a GSON serialization here if you want
// This is not a robust implementation
return Integer.toString(id) + "-" + title;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4013 次 |
| 最近记录: |