提交 a19609a1 编写于 作者: J Jake Wharton

Add example of using JSON converter as a String converter.

This also adds the Retrofit instance as a param to the string converter to allow it to delegate to others directly. This brings it into parity with the method signatures of the other converter methods anyway.
上级 bc7226b0
......@@ -47,7 +47,8 @@ final class BuiltInConverters extends Converter.Factory {
return null;
}
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations) {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == String.class) {
return StringConverter.INSTANCE;
}
......
......@@ -69,7 +69,8 @@ public interface Converter<F, T> {
* {@link Header @Header}, {@link Path @Path}, {@link Query @Query}, and
* {@link QueryMap @QueryMap} values.
*/
public Converter<?, String> stringConverter(Type type, Annotation[] annotations) {
public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
......
......@@ -343,7 +343,7 @@ public final class Retrofit {
for (int i = 0, count = converterFactories.size(); i < count; i++) {
Converter<?, String> converter =
converterFactories.get(i).stringConverter(type, annotations);
converterFactories.get(i).stringConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<T, String>) converter;
......
......@@ -354,7 +354,8 @@ public final class RetrofitTest {
@Test public void parameterAnnotationsPassedToStringConverter() {
final AtomicReference<Annotation[]> annotationsRef = new AtomicReference<>();
class MyConverterFactory extends Converter.Factory {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations) {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
annotationsRef.set(annotations);
return new Converter<Object, String>() {
......@@ -377,7 +378,8 @@ public final class RetrofitTest {
@Test public void stringConverterNotCalledForString() {
class MyConverterFactory extends Converter.Factory {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations) {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
throw new AssertionError();
}
}
......@@ -394,7 +396,8 @@ public final class RetrofitTest {
@Test public void stringConverterReturningNullResultsInDefault() {
final AtomicBoolean factoryCalled = new AtomicBoolean();
class MyConverterFactory extends Converter.Factory {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations) {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
factoryCalled.set(true);
return null;
}
......@@ -945,12 +948,12 @@ public final class RetrofitTest {
.addConverterFactory(factory)
.build();
doReturn(expectedAdapter).when(factory).stringConverter(type, annotations);
doReturn(expectedAdapter).when(factory).stringConverter(type, annotations, retrofit);
Converter<?, String> actualAdapter = retrofit.stringConverter(type, annotations);
assertThat(actualAdapter).isSameAs(expectedAdapter);
verify(factory).stringConverter(type, annotations);
verify(factory).stringConverter(type, annotations, retrofit);
verifyNoMoreInteractions(factory);
}
......
......@@ -39,7 +39,8 @@ public final class NonMatchingConverterFactory extends Converter.Factory {
return null;
}
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations) {
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
called = true;
return null;
}
......
/*
* Copyright (C) 2016 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.retrofit;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okio.Buffer;
import retrofit2.Call;
import retrofit2.Converter;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
public final class JsonQueryParameters {
@Retention(RUNTIME)
@interface Json {
}
static class JsonStringConverterFactory extends Converter.Factory {
private final Converter.Factory delegateFactory;
JsonStringConverterFactory(Converter.Factory delegateFactory) {
this.delegateFactory = delegateFactory;
}
@Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
for (Annotation annotation : annotations) {
if (annotation instanceof Json) {
// NOTE: If you also have a JSON converter factory installed in addition to this factory,
// you can call retrofit.requestBodyConverter(type, annotations) instead of having a
// reference to it explicitly as a field.
Converter<?, RequestBody> delegate =
delegateFactory.requestBodyConverter(type, annotations, retrofit);
return new DelegateToStringConverter<>(delegate);
}
}
return null;
}
static class DelegateToStringConverter<T> implements Converter<T, String> {
private final Converter<T, RequestBody> delegate;
DelegateToStringConverter(Converter<T, RequestBody> delegate) {
this.delegate = delegate;
}
@Override public String convert(T value) throws IOException {
Buffer buffer = new Buffer();
delegate.convert(value).writeTo(buffer);
return buffer.readUtf8();
}
}
}
static class Filter {
public final String userId;
public Filter(String userId) {
this.userId = userId;
}
}
interface Service {
@GET("/filter")
Call<ResponseBody> example(@Json @Query("value") Filter value);
}
public static void main(String... args) throws IOException, InterruptedException {
MockWebServer server = new MockWebServer();
server.start();
server.enqueue(new MockResponse());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(new JsonStringConverterFactory(GsonConverterFactory.create()))
.build();
Service service = retrofit.create(Service.class);
Call<ResponseBody> call = service.example(new Filter("123"));
Response<ResponseBody> response = call.execute();
// TODO handle user response...
// Print the request path that the server saw to show the JSON query param:
RecordedRequest recordedRequest = server.takeRequest();
System.out.println(recordedRequest.getPath());
server.shutdown();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册