2018-02-25 Retrofit自定义Converter之StringConverterFactory

之前写过一篇 浅谈Retrofit封装-让框架更加简洁易用 里面采用的是GsonConverterFactory,对于retrofit的返回类型要求只能是: 具体对象、jsonObject、jsonArray这三种。由于服务器返回的基础数据格式不固定,所以封装请求类的时候每个请求方式都要封装两个方法,而retrofit又必须添加一种解析器,本人对代码有洁癖,抽时间写了个StringConverterFactory将数据解析成最基本的String返回。 

参考GsonConverterFactory源码,自定义解析器还是比较好写的,一共三个类,直接贴了

解析器 工厂

packagecom.sunshine.retrofit.converter;importjava.lang.annotation.Annotation;importjava.lang.reflect.Type;importokhttp3.RequestBody;importokhttp3.ResponseBody;importretrofit2.Converter;importretrofit2.Retrofit;

/**

* Created by 耿 on 2016/9/6.

*/

publicclassStringConverterFactoryextendsConverter.Factory{

publicstaticStringConverterFactorycreate() {

          return newStringConverterFactory();   

 }privateStringConverterFactory() {  

  }

@OverridepublicConverterresponseBodyConverter(Type type, Annotation[] annotations,    Retrofit retrofit) {

         return newStringResponseBodyConverter();   

 }

@OverridepublicConverterrequestBodyConverter(Type type,   Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {

         return newStringRequestBodyConverter();  

 }

}

Response响应体类

packagecom.sunshine.retrofit.converter;importjava.io.IOException;importokhttp3.ResponseBody;importretrofit2.Converter;

/**

* Created by 耿 on 2016/9/6.

*/

publicclassStringResponseBodyConverterimplementsConverter {

@Overridepublic String convert(ResponseBody value)throwsIOException {

try{

returnvalue.string();      

  }finally{       

     value.close();    

    }  

 }}

Request 请求体类

packagecom.sunshine.retrofit.converter;importjava.io.IOException;importjava.io.OutputStreamWriter;importjava.io.Writer;importjava.nio.charset.Charset;importokhttp3.MediaType;importokhttp3.RequestBody;importokio.Buffer;importretrofit2.Converter;

/**

* Created by 耿 on 2016/9/6.

*/

publicclassStringRequestBodyConverterimplementsConverter {

privatestaticfinalMediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");privatestaticfinalCharset UTF_8 = Charset.forName("UTF-8");  

  StringRequestBodyConverter() {    }

@Overridepublic RequestBody convert(String value)throwsIOException {      

  Buffer buffer =newBuffer();      

  Writer writer =newOutputStreamWriter(buffer.outputStream(), UTF_8);     

   writer.write(value);        

writer.close();

return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); 

   }

}

在构建retrofit时替换掉原来的GsonConverterFactory就可以了

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL +"/").addConverterFactory(StringConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).client(OkhttpProvidede.okHttpClient(mAppliactionContext, BASE_URL, SERVERS)).build();

这里要注意,retrofit对于解析器是由添加的顺序分别试用的,解析成功就直接返回,失败则调用下一个解析器。如果你们的服务器一开始基本返回格式不固定,而后来在你的建议或者坚持下,大发善心的把后面新需求的API的返回格式都固定了的话,可以按如下代码的方式将GsonConverterFactory添加在StringConverterFactory前面。这样如果是固定格式的就可以直接解析返回了。

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL +"/").addConverterFactory(GsonConverterFactory.create()).addConverterFactory(StringConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).client(OkhttpProvidede.okHttpClient(mAppliactionContext, BASE_URL, SERVERS)).build();

然后以后调用请求就可以直接

newHttpUtil.Builder("favorite_authorized/list?page=1")                    .Version()                    .CacheTime("3600*24")                    .Params("carId", sb.toString())                    .Params(sortMap_)                    .Success((s) -> {                        ld_.dismiss();                        BaseModel model =newBaseModel(s);                    }).Error((v) -> {                        ld_.dismiss();                        handler_.obtainMessage(MSG, v[1]).sendToTarget();                    }).get();        });


再也不用去管返回格式是jsonObject还是jsonArray了。

你可能感兴趣的:(2018-02-25 Retrofit自定义Converter之StringConverterFactory)