/*
* 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, new Annotation[0], 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 {
final String userId;
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();
}
}