提交 9fcb0d28 编写于 作者: E Eric Denman

Merge remote-tracking branch 'origin/injectable-gson'

* origin/injectable-gson:
  Review tweaks.
  Makes the gson instance Guice injectable rather than hard coding it. Clients will have to discover the just-one-gson optimization on their own.
workspace.xml
dictionaries/
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value />
</option>
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
<list size="1">
<item index="0" class="java.lang.String" itemvalue="com.google.inject.Inject" />
</list>
</component>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
......
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>
\ No newline at end of file
......@@ -13,6 +13,7 @@ import org.apache.http.client.methods.HttpUriRequest;
import retrofit.core.Callback;
import retrofit.core.MainThread;
import retrofit.core.ProgressListener;
import retrofit.internal.gson.Gson;
import retrofit.io.ByteSink;
import java.io.ByteArrayOutputStream;
......@@ -59,7 +60,7 @@ public class FetcherTest extends TestCase {
replayAll();
Fetcher fetcher = new Fetcher(new Provider<HttpClient>() {
Fetcher fetcher = new Fetcher(new Gson(), new Provider<HttpClient>() {
public HttpClient get() {
return httpClient;
}
......
......@@ -2,21 +2,22 @@
package retrofit.http;
import com.google.inject.name.Named;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.Set;
import java.util.UUID;
import junit.framework.TestCase;
import org.apache.http.HttpMessage;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import retrofit.core.Callback;
import retrofit.internal.gson.Gson;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.Set;
import java.util.UUID;
/** @author Eric Denman (edenman@squareup.com) */
public class HttpRequestBuilderTest extends TestCase {
public static final String API_URL = "http://taqueria.com/lengua/taco";
public static final Headers BLANK_HEADERS = new Headers() {
@Override public void setOn(HttpMessage message, String mimeType) {
......@@ -183,7 +184,7 @@ public class HttpRequestBuilderTest extends TestCase {
}
private HttpUriRequest build(Method method, Object[] args) throws URISyntaxException {
return new HttpRequestBuilder().setMethod(method)
return new HttpRequestBuilder(new Gson()).setMethod(method)
.setArgs(args)
.setApiUrl(API_URL)
.setHeaders(BLANK_HEADERS)
......
......@@ -4,9 +4,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.Executor;
import junit.framework.TestCase;
import org.apache.http.HttpMessage;
import org.apache.http.HttpResponse;
......@@ -24,6 +21,11 @@ import org.easymock.IAnswer;
import org.junit.Before;
import retrofit.core.Callback;
import retrofit.core.MainThread;
import retrofit.internal.gson.Gson;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.Executor;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
......@@ -32,7 +34,6 @@ import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static retrofit.http.GsonProvider.gson;
import static retrofit.http.RestAdapter.service;
public class RestAdapterTest extends TestCase {
......@@ -50,6 +51,7 @@ public class RestAdapterTest extends TestCase {
private Headers mockHeaders;
@SuppressWarnings("rawtypes") private Callback mockCallback;
private HttpResponse mockResponse;
private Gson gson = new Gson();
@Override @Before public void setUp() throws Exception {
mockHttpClient = createMock(HttpClient.class);
......@@ -260,7 +262,7 @@ public class RestAdapterTest extends TestCase {
expectExecution(mockMainThread); // For call()
expectSetOnWithRequest(requestClass, requestUrl);
Response response = new Response("some text");
expectResponseCalls(gson().toJson(response));
expectResponseCalls(gson.toJson(response));
expectHttpClientExecute();
expectCallbacks(response);
}
......
......@@ -4,14 +4,15 @@ package retrofit.http;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.inject.Inject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ResponseHandler;
import org.apache.http.entity.BufferedHttpEntity;
import retrofit.core.Callback;
import static retrofit.http.GsonProvider.gson;
import retrofit.internal.gson.Gson;
/**
* Support for response handlers that invoke {@link Callback}.
......@@ -30,8 +31,11 @@ public abstract class CallbackResponseHandler<T>
private static final int GATEWAY_TIMEOUT = 504;
private final Callback<T> callback;
private final Gson gson;
public CallbackResponseHandler(Callback<T> callback) {
protected CallbackResponseHandler(Gson gson, Callback<T> callback) {
this.gson = gson;
this.callback = callback;
}
......@@ -135,11 +139,11 @@ public abstract class CallbackResponseHandler<T>
/**
* Parses a server error message.
*/
private static String parseServerMessage(int statusCode, String body) {
private String parseServerMessage(int statusCode, String body) {
if (statusCode == BAD_GATEWAY || statusCode == GATEWAY_TIMEOUT
|| statusCode < 500) {
try {
ServerError serverError = gson().fromJson(body, ServerError.class);
ServerError serverError = gson.fromJson(body, ServerError.class);
if (serverError != null) return serverError.message;
} catch (Throwable t) {
// The server error takes precedence.
......
......@@ -14,6 +14,7 @@ import org.apache.http.client.methods.HttpGet;
import retrofit.core.Callback;
import retrofit.core.MainThread;
import retrofit.core.ProgressListener;
import retrofit.internal.gson.Gson;
import retrofit.io.ByteSink;
import static retrofit.core.internal.Objects.nonNull;
......@@ -29,12 +30,13 @@ public class Fetcher {
// TODO: Support conditional get.
private final Gson gson;
private final Provider<HttpClient> httpClientProvider;
private final Executor executor;
private final MainThread mainThread;
@Inject Fetcher(Provider<HttpClient> httpClientProvider, Executor executor,
MainThread mainThread) {
@Inject Fetcher(Gson gson, Provider<HttpClient> httpClientProvider, Executor executor, MainThread mainThread) {
this.gson = gson;
this.httpClientProvider = httpClientProvider;
this.executor = executor;
this.mainThread = mainThread;
......@@ -57,7 +59,7 @@ public class Fetcher {
executor.execute(new Runnable() {
public void run() {
try {
httpClientProvider.get().execute(get, new DownloadHandler(destination,
httpClientProvider.get().execute(get, new DownloadHandler(gson, destination,
uiCallback, progressListener, mainThread));
} catch (IOException e) {
logger.log(Level.WARNING, "fetch exception", e);
......@@ -81,10 +83,10 @@ public class Fetcher {
private final MainThread mainThread;
private final ProgressUpdate progressUpdate = new ProgressUpdate();
DownloadHandler(ByteSink.Factory destination,
DownloadHandler(Gson gson, ByteSink.Factory destination,
UiCallback<Void> callback, ProgressListener progressListener,
MainThread mainThread) {
super(callback);
super(gson, callback);
this.destination = destination;
this.progressListener = progressListener;
this.mainThread = mainThread;
......
// Copyright 2011 Square, Inc.
package retrofit.http;
import retrofit.internal.gson.Gson;
/**
* Creating a Gson instance is relatively expensive (70ms on my MBP), and Gson is thread-safe.
* Create the instance once so we're not constantly creating them.
*
* @author Eric Denman (edenman@squareup.com)
*/
public class GsonProvider {
/** Lazily loads the Gson instance. */
private static class Holder {
static final Gson gson = new Gson();
}
public static Gson gson() {
return Holder.gson;
}
}
package retrofit.http;
import org.apache.http.HttpEntity;
import retrofit.core.Callback;
import retrofit.internal.gson.Gson;
import retrofit.internal.gson.JsonParseException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import retrofit.core.Callback;
import retrofit.internal.gson.JsonParseException;
import static retrofit.http.GsonProvider.gson;
/**
* Converts JSON response to an object using Gson and then passes it to {@link
......@@ -19,16 +19,18 @@ class GsonResponseHandler<T> extends CallbackResponseHandler<T> {
private static final Logger logger =
Logger.getLogger(GsonResponseHandler.class.getName());
private final Gson gson;
private final Type type;
private GsonResponseHandler(Type type, Callback<T> callback) {
super(callback);
private GsonResponseHandler(Gson gson, Type type, Callback<T> callback) {
super(gson, callback);
this.gson = gson;
this.type = type;
}
static <T> GsonResponseHandler<T> create(Type type,
static <T> GsonResponseHandler<T> create(Gson gson, Type type,
Callback<T> callback) {
return new GsonResponseHandler<T>(type, callback);
return new GsonResponseHandler<T>(gson, type, callback);
}
@Override protected T parse(HttpEntity entity) throws IOException,
......@@ -47,7 +49,7 @@ class GsonResponseHandler<T> extends CallbackResponseHandler<T> {
* We derived type from Callback<T>, so we know we're safe.
*/
@SuppressWarnings("unchecked")
T t = (T) gson().fromJson(in, type);
T t = (T) gson.fromJson(in, type);
return t;
} catch (JsonParseException e) {
// The server returned us bad JSON!
......
package retrofit.http;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicNameValuePair;
import retrofit.internal.gson.Gson;
import retrofit.io.MimeType;
import retrofit.io.TypedBytes;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
......@@ -14,13 +22,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicNameValuePair;
import retrofit.io.MimeType;
import retrofit.io.TypedBytes;
import static retrofit.http.GsonProvider.gson;
/**
* Builds HTTP requests from Java method invocations. Handles "path parameters"
......@@ -36,6 +37,8 @@ import static retrofit.http.GsonProvider.gson;
final class HttpRequestBuilder {
private static final Logger logger = Logger.getLogger(HttpRequestBuilder.class.getName());
private final Gson gson;
private Method javaMethod;
private Object[] args;
private String apiUrl;
......@@ -44,6 +47,10 @@ final class HttpRequestBuilder {
private List<NameValuePair> nonPathParams;
private RequestLine requestLine;
private TypedBytes singleEntity;
HttpRequestBuilder(Gson gson) {
this.gson = gson;
}
HttpRequestBuilder setMethod(Method method) {
this.javaMethod = method;
......@@ -270,7 +277,7 @@ final class HttpRequestBuilder {
}
protected String toJson() {
return gson().toJson(obj);
return gson.toJson(obj);
}
}
}
\ No newline at end of file
......@@ -21,6 +21,7 @@ import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import retrofit.core.Callback;
import retrofit.core.MainThread;
import retrofit.internal.gson.Gson;
/**
* Converts Java method calls to Rest calls.
......@@ -36,6 +37,7 @@ import retrofit.core.MainThread;
@Inject private Executor executor;
@Inject private MainThread mainThread;
@Inject private Headers headers;
@Inject private Gson gson;
@Inject(optional = true) private HttpProfiler profiler;
/**
......@@ -102,7 +104,7 @@ import retrofit.core.MainThread;
try {
// Construct HTTP request.
HttpUriRequest request = new HttpRequestBuilder()
HttpUriRequest request = new HttpRequestBuilder(gson)
.setMethod(method)
.setArgs(args)
.setApiUrl(server.apiUrl())
......@@ -117,7 +119,7 @@ import retrofit.core.MainThread;
request.getURI());
final GsonResponseHandler<?> gsonResponseHandler =
GsonResponseHandler.create(resultType, callback);
GsonResponseHandler.create(gson, resultType, callback);
// Optionally wrap the response handler for server call profiling.
ResponseHandler<Void> rh = (profiler == null) ?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册