[exonerator/master] Replace Gson with Jackson.

commit e15c3a64610c04b2db3dcbbd8f7f7890c9a3101e Author: Karsten Loesing <karsten.loesing@gmx.net> Date: Tue May 22 20:58:18 2018 +0200 Replace Gson with Jackson. Implements #26163. --- CHANGELOG.md | 3 ++ build.xml | 6 ++- .../metrics/exonerator/QueryResponse.java | 47 +++++++++------------- .../metrics/exonerator/QueryResponseTest.java | 5 ++- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b80bf4..9766439 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changes in version 2.0.3 - 2018-0?-?? + * Medium changes + - Replace Gson with Jackson. + * Minor changes - Remove duplicate [] surrounding suggested IPv6 addresses. diff --git a/build.xml b/build.xml index b82ce0a..b0fced5 100644 --- a/build.xml +++ b/build.xml @@ -9,7 +9,7 @@ <property name="javadoc-title" value="ExoneraTor API Documentation"/> <property name="implementation-title" value="ExoneraTor" /> <property name="release.version" value="2.0.2-dev" /> - <property name="metricslibversion" value="2.1.1" /> + <property name="metricslibversion" value="2.4.0" /> <property name="jetty.version" value="-9.2.21.v20170120" /> <property name="warfile" value="exonerator-${release.version}.war"/> @@ -34,7 +34,9 @@ <patternset id="common" > <include name="commons-codec-1.10.jar"/> <include name="commons-lang3-3.5.jar"/> - <include name="gson-2.4.jar" /> + <include name="jackson-annotations-2.8.6.jar"/> + <include name="jackson-core-2.8.6.jar"/> + <include name="jackson-databind-2.8.6.jar"/> <include name="logback-core-1.1.9.jar" /> <include name="logback-classic-1.1.9.jar" /> <include name="postgresql-9.4.1212.jar"/> diff --git a/src/main/java/org/torproject/metrics/exonerator/QueryResponse.java b/src/main/java/org/torproject/metrics/exonerator/QueryResponse.java index 96e32cc..6a77565 100644 --- a/src/main/java/org/torproject/metrics/exonerator/QueryResponse.java +++ b/src/main/java/org/torproject/metrics/exonerator/QueryResponse.java @@ -3,68 +3,60 @@ package org.torproject.metrics.exonerator; -import com.google.gson.Gson; -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.io.Reader; /** Query response from the ExoneraTor database. */ public class QueryResponse { - @Expose(serialize = false, deserialize = false) private static Logger logger = LoggerFactory.getLogger(QueryResponse.class); /* Actual version implemented by this class. */ - @Expose(serialize = false, deserialize = false) private static final String VERSION = "1.0"; /* Don't accept query responses with versions lower than this. */ - @Expose(serialize = false, deserialize = false) private static final String FIRSTRECOGNIZEDVERSION = "1.0"; /* Don't accept query responses with this version or higher. */ - @Expose(serialize = false, deserialize = false) private static final String FIRSTUNRECOGNIZEDVERSION = "2.0"; + private static ObjectMapper objectMapper = new ObjectMapper() + .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE) + .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) + .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE) + .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + /** Version of this response format. */ - @Expose String version = VERSION; /** Query IP address passed in the request; never <code>null</code>. */ - @Expose - @SerializedName("query_address") String queryAddress; /** Query date passed in the request; never <code>null</code>. */ - @Expose - @SerializedName("query_date") String queryDate; /** ISO-formatted valid-after time of the first status contained in the * database; only <code>null</code> if the database is empty. */ - @Expose - @SerializedName("first_date_in_database") String firstDateInDatabase; /** ISO-formatted valid-after time of the last status contained in the * database; only <code>null</code> if the database is empty. */ - @Expose - @SerializedName("last_date_in_database") String lastDateInDatabase; /** Whether there is at least one relevant status in the database on or within * a day of the requested date; <code>null</code> if the database is empty. */ - @Expose - @SerializedName("relevant_statuses") Boolean relevantStatuses; /** All matches for the given IP address and date; <code>null</code> if there * were no matches at all. */ - @Expose Match[] matches; /** Constructor for Gson. */ @@ -85,16 +77,16 @@ public class QueryResponse { } /** Return JSON string for given QueryResponse. */ - public static String toJson(QueryResponse response) { - return new Gson().toJson(response); + public static String toJson(QueryResponse response) throws IOException { + return objectMapper.writeValueAsString(response); } /** Return QueryResponse parsed from the given input stream, or * {@code null} if something fails or an unrecognized version is found. */ public static QueryResponse fromJson(Reader reader) { - Gson gson = new Gson(); try { - QueryResponse response = gson.fromJson(reader, QueryResponse.class); + QueryResponse response = objectMapper.readValue(reader, + QueryResponse.class); if (null == response || null == response.version) { logger.warn("Response is either empty or does not contain " + "version information."); @@ -107,7 +99,10 @@ public class QueryResponse { return null; } return response; - } catch (RuntimeException e) { + } catch (IOException | RuntimeException e) { + /* We're catching RuntimeException here, rather than IOException, so that + * we return null if anything goes wrong, including cases that we did not + * anticipate. */ logger.error("JSON decoding failed.", e); } return null; @@ -148,8 +143,6 @@ public class QueryResponse { /** All known IP addresses in the same /24 or /48 network; <code>null</code> * if there were direct matches for the given IP address. */ - @Expose - @SerializedName("nearby_addresses") String[] nearbyAddresses; } diff --git a/src/test/java/org/torproject/metrics/exonerator/QueryResponseTest.java b/src/test/java/org/torproject/metrics/exonerator/QueryResponseTest.java index d188f15..5390340 100644 --- a/src/test/java/org/torproject/metrics/exonerator/QueryResponseTest.java +++ b/src/test/java/org/torproject/metrics/exonerator/QueryResponseTest.java @@ -11,6 +11,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import java.util.Collection; @@ -103,7 +104,7 @@ public class QueryResponseTest { } @Test - public void testJsonReading() { + public void testJsonReading() throws IOException { if (null == this.queryResponse) { assertNull(QueryResponse.fromJson(new StringReader(this.json))); } else { @@ -113,7 +114,7 @@ public class QueryResponseTest { } @Test - public void testJsonWriting() { + public void testJsonWriting() throws IOException { if (null == this.queryResponse) { return; }
participants (1)
-
karsten@torproject.org