我正在尝试使用自定义转换器进行改造
RestAdapter.Builder builder = new RestAdapter.Builder() .setEndpoint(BuildConfig.BASE_SERVER_ENDPOINT) .setClient(new OkClient(client)).setConverter(new CitationResponseConverter()) .setLogLevel(RestAdapter.LogLevel.FULL);
以下是我的自定义转换器
public class CitationResponseConverter implements Converter { @Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException { try { InputStream in = typedInput.in(); // convert the typedInput to String String string = fromStream(in); in.close(); // we are responsible to close the InputStream after use if (String.class.equals(type)) { return string; } else { return new Gson().fromJson(string, type); // convert to the supplied type, typically Object, JsonObject or Map<String, Object> } } catch (Exception e) { // a lot may happen here, whatever happens throw new ConversionException( e); // wrap it into ConversionException so retrofit can process it } } @Override public TypedOutput toBody(Object object) { return null; } private static String fromStream(InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder out = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { out.append(line); out.append("\r\n"); } return out.toString(); } }
我收到以下错误
retrofit.RetrofitError: method POST must have a request body.
在尝试进行此api调用时
@POST("/service/citations") Observable<CitationMain> getCitations(@Body CitationRequestBody body);
我想转换器正在覆盖对api调用的请求,如何避免这种情况并传递在改造服务中定义的请求主体。
回应:
{ "citations": [ { "coverdatestart": "2015-05-01", "coverimage": [ "09699961/S0969996115X00040/cov200h.gif", "09699961/S0969996115X00040/cov150h.gif" ], "pubyear": "2015", "refimage": [ "09699961/S0969996115X00040/S0969996115000522/gr1-t.gif", "09699961/S0969996115X00040/S0969996115000522/gr1.jpg" ], "volissue": "Volume 77", "volume": "77" }, { "pubdatetxt": "19700101", "refimage": "mma:otto_4_9781455748600/9781455748600_0020", } ] }
我会做这样的事情:
public class StringList extends ArrayList<String> { // Empty on purpose. The class is here only to be recognized by Gson } public class CitationMain { @SerializedName("field_name_here") StringList values; // Your other fields }
然后在创建RestAdapter时:
public class StringListDeserializer implements JsonDeserializer<StringList> { @Override public StringList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { StringList value = new StringList(); if (json.isJsonArray()) { for (JsonElement element : json.getAsJsonArray()) { value.add(element.getAsString()); } } else { value.add(json.getAsString()); } return value; } }
然后:
Gson gson = new GsonBuilder() .registerTypeAdapter(StringList.class, new StringListDeserializer()) .create(); RestAdapter.Builder builder = new RestAdapter.Builder() //... .setConverter(new GsonConverter(gson));
这不是理想的,因为对象是自定义的,但是我现在能想到的任何其他解决方案都更加复杂。
这里的反序列化器专门为声明为的字段注册StringList,将处理单个字符串的情况以及字符串数组的情况。任何其他字段类型将使用默认的反序列化过程。
StringList