Android 对随响应返回的请求进行改装设置标记

Android 对随响应返回的请求进行改装设置标记,android,retrofit,Android,Retrofit,基本上,我的问题很简单。我使用改型作为与我无法控制的服务器通信的框架。我想在我的请求上设置某种类型的标记,该标记将在响应中自动返回。你知道如何做到这一点吗?我找到了一个复杂而不酷的方法 0。在请求和响应类型中添加标记字段 1。自定义okhttp3.RequestBody添加标记字段: 2。自定义okhttp3.ResponseBody添加标记字段: .addInterceptor(new Interceptor() { @Override

基本上,我的问题很简单。我使用改型作为与我无法控制的服务器通信的框架。我想在我的请求上设置某种类型的标记,该标记将在响应中自动返回。你知道如何做到这一点吗?

我找到了一个复杂而不酷的方法

0。在请求和响应类型中添加标记字段

1。自定义
okhttp3.RequestBody
添加标记字段:

2。自定义
okhttp3.ResponseBody
添加标记字段:

.addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response response = chain.proceed(chain.request());
                        if (request.body() instanceof TagRequestBody) {
                            TagResponseBody responseBody = new TagResponseBody(response.body());
                            responseBody.arg = ((TagRequestBody) request.body()).arg;
                            response = response.newBuilder()
                                    .body(responseBody)
                                    .build();
                        }
                        return response;
                    }
                })
3。自定义
Converter.Factory
设置并获取标签:

例如,我对
GsonResponseBodyConverter
GsonRequestBodyConverter
做了一些更改:

TagGsonRequestBodyConverter.java:

@Override public RequestBody convert(T value) throws IOException {
    Buffer buffer = new Buffer();
    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
    JsonWriter jsonWriter = gson.newJsonWriter(writer);
    adapter.write(jsonWriter, value);
    jsonWriter.close();

    TagRequestBody requestBody = TagRequestBody.create(MEDIA_TYPE, buffer.readByteString());
    requestBody = value.tag;//just for example ,you will need to check type here
    return requestBody;
  }
TagGsonResponseBodyConverter.java:

    @Override public T convert(ResponseBody source) throws IOException {
try {
  //the ugly part,for that retrofit will wrap the responseBody with ExceptionCatchingRequestBody.(ExceptionCatchingRequestBody extends ResponseBody) 
  ResponseBody value = source;
  if (value.getClass().getSimpleName().equals("ExceptionCatchingRequestBody")){
    ResponseBody temp = null;
    try {
      Field f = source.getClass().getDeclaredField("delegate");
      f.setAccessible(true);
      temp = (T) f.get(value);
    } catch (Exception e) {
      e.printStackTrace();
    }
    value = temp != null?temp:value;
  }
  T t = adapter.fromJson(source.charStream());
  if (value instanceof TagResponseBody) {
    t.tag = ((TagResponseBody)value).tag;
  }
  return t;
} finally {
  value.close();
}
}

4。在创建改造的okhttpClient时添加拦截器,将标记从TagRequestBody传递到TagResponseBody:

.addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response response = chain.proceed(chain.request());
                        if (request.body() instanceof TagRequestBody) {
                            TagResponseBody responseBody = new TagResponseBody(response.body());
                            responseBody.arg = ((TagRequestBody) request.body()).arg;
                            response = response.newBuilder()
                                    .body(responseBody)
                                    .build();
                        }
                        return response;
                    }
                })
因此,标签由:

RequestDataWithTag--CustGsonRequestBodyConverter-->RequestBodyWithTag--Interceptor-->ResponseBodyWithTag--CustGsonResponseBodyConverter-->ResponseDataWithTag

请参阅此处@Etha123您想要发送的值的类型。您可以设置自定义头,但这将要求服务器在响应中重新设置头。通用数据没有任何当前请求/响应头。