Merge pull request #771 from google/jw/global-leniency
Add setting for leniency on Gson instance.
This commit is contained in:
commit
2ab776b5f5
@ -101,6 +101,12 @@ import com.google.gson.stream.MalformedJsonException;
|
|||||||
*/
|
*/
|
||||||
public final class Gson {
|
public final class Gson {
|
||||||
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
||||||
|
static final boolean DEFAULT_LENIENT = false;
|
||||||
|
static final boolean DEFAULT_PRETTY_PRINT = false;
|
||||||
|
static final boolean DEFAULT_ESCAPE_HTML = true;
|
||||||
|
static final boolean DEFAULT_SERIALIZE_NULLS = false;
|
||||||
|
static final boolean DEFAULT_COMPLEX_MAP_KEYS = false;
|
||||||
|
static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false;
|
||||||
|
|
||||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
|
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
|
||||||
|
|
||||||
@ -124,6 +130,7 @@ public final class Gson {
|
|||||||
private final boolean htmlSafe;
|
private final boolean htmlSafe;
|
||||||
private final boolean generateNonExecutableJson;
|
private final boolean generateNonExecutableJson;
|
||||||
private final boolean prettyPrinting;
|
private final boolean prettyPrinting;
|
||||||
|
private final boolean lenient;
|
||||||
|
|
||||||
final JsonDeserializationContext deserializationContext = new JsonDeserializationContext() {
|
final JsonDeserializationContext deserializationContext = new JsonDeserializationContext() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -177,15 +184,16 @@ public final class Gson {
|
|||||||
*/
|
*/
|
||||||
public Gson() {
|
public Gson() {
|
||||||
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
|
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
|
||||||
Collections.<Type, InstanceCreator<?>>emptyMap(), false, false, DEFAULT_JSON_NON_EXECUTABLE,
|
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
|
||||||
true, false, false, LongSerializationPolicy.DEFAULT,
|
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
|
||||||
Collections.<TypeAdapterFactory>emptyList());
|
DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
|
||||||
|
LongSerializationPolicy.DEFAULT, Collections.<TypeAdapterFactory>emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
|
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
|
||||||
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
|
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
|
||||||
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
|
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
|
||||||
boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
|
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
|
||||||
LongSerializationPolicy longSerializationPolicy,
|
LongSerializationPolicy longSerializationPolicy,
|
||||||
List<TypeAdapterFactory> typeAdapterFactories) {
|
List<TypeAdapterFactory> typeAdapterFactories) {
|
||||||
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
||||||
@ -193,6 +201,7 @@ public final class Gson {
|
|||||||
this.generateNonExecutableJson = generateNonExecutableGson;
|
this.generateNonExecutableJson = generateNonExecutableGson;
|
||||||
this.htmlSafe = htmlSafe;
|
this.htmlSafe = htmlSafe;
|
||||||
this.prettyPrinting = prettyPrinting;
|
this.prettyPrinting = prettyPrinting;
|
||||||
|
this.lenient = lenient;
|
||||||
|
|
||||||
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||||
|
|
||||||
@ -704,6 +713,15 @@ public final class Gson {
|
|||||||
return jsonWriter;
|
return jsonWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new JSON writer configured for the settings on this Gson instance.
|
||||||
|
*/
|
||||||
|
public JsonReader newJsonReader(Reader reader) {
|
||||||
|
JsonReader jsonReader = new JsonReader(reader);
|
||||||
|
jsonReader.setLenient(lenient);
|
||||||
|
return jsonReader;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the JSON for {@code jsonElement} to {@code writer}.
|
* Writes the JSON for {@code jsonElement} to {@code writer}.
|
||||||
* @throws JsonIOException if there was a problem writing to the writer
|
* @throws JsonIOException if there was a problem writing to the writer
|
||||||
@ -795,7 +813,7 @@ public final class Gson {
|
|||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
|
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
|
||||||
JsonReader jsonReader = new JsonReader(json);
|
JsonReader jsonReader = newJsonReader(json);
|
||||||
Object object = fromJson(jsonReader, classOfT);
|
Object object = fromJson(jsonReader, classOfT);
|
||||||
assertFullConsumption(object, jsonReader);
|
assertFullConsumption(object, jsonReader);
|
||||||
return Primitives.wrap(classOfT).cast(object);
|
return Primitives.wrap(classOfT).cast(object);
|
||||||
@ -822,7 +840,7 @@ public final class Gson {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
|
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
|
||||||
JsonReader jsonReader = new JsonReader(json);
|
JsonReader jsonReader = newJsonReader(json);
|
||||||
T object = (T) fromJson(jsonReader, typeOfT);
|
T object = (T) fromJson(jsonReader, typeOfT);
|
||||||
assertFullConsumption(object, jsonReader);
|
assertFullConsumption(object, jsonReader);
|
||||||
return object;
|
return object;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
@ -31,6 +32,14 @@ import com.google.gson.internal.Excluder;
|
|||||||
import com.google.gson.internal.bind.TypeAdapters;
|
import com.google.gson.internal.bind.TypeAdapters;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import static com.google.gson.Gson.DEFAULT_COMPLEX_MAP_KEYS;
|
||||||
|
import static com.google.gson.Gson.DEFAULT_ESCAPE_HTML;
|
||||||
|
import static com.google.gson.Gson.DEFAULT_JSON_NON_EXECUTABLE;
|
||||||
|
import static com.google.gson.Gson.DEFAULT_LENIENT;
|
||||||
|
import static com.google.gson.Gson.DEFAULT_PRETTY_PRINT;
|
||||||
|
import static com.google.gson.Gson.DEFAULT_SERIALIZE_NULLS;
|
||||||
|
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
|
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
|
||||||
* options other than the default. For {@link Gson} with default configuration, it is simpler to
|
* options other than the default. For {@link Gson} with default configuration, it is simpler to
|
||||||
@ -74,15 +83,16 @@ public final class GsonBuilder {
|
|||||||
private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||||
/** tree-style hierarchy factories. These come after factories for backwards compatibility. */
|
/** tree-style hierarchy factories. These come after factories for backwards compatibility. */
|
||||||
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
|
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
|
||||||
private boolean serializeNulls;
|
private boolean serializeNulls = DEFAULT_SERIALIZE_NULLS;
|
||||||
private String datePattern;
|
private String datePattern;
|
||||||
private int dateStyle = DateFormat.DEFAULT;
|
private int dateStyle = DateFormat.DEFAULT;
|
||||||
private int timeStyle = DateFormat.DEFAULT;
|
private int timeStyle = DateFormat.DEFAULT;
|
||||||
private boolean complexMapKeySerialization;
|
private boolean complexMapKeySerialization = DEFAULT_COMPLEX_MAP_KEYS;
|
||||||
private boolean serializeSpecialFloatingPointValues;
|
private boolean serializeSpecialFloatingPointValues = DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
||||||
private boolean escapeHtmlChars = true;
|
private boolean escapeHtmlChars = DEFAULT_ESCAPE_HTML;
|
||||||
private boolean prettyPrinting;
|
private boolean prettyPrinting = DEFAULT_PRETTY_PRINT;
|
||||||
private boolean generateNonExecutableJson;
|
private boolean generateNonExecutableJson = DEFAULT_JSON_NON_EXECUTABLE;
|
||||||
|
private boolean lenient = DEFAULT_LENIENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
|
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
|
||||||
@ -351,6 +361,19 @@ public final class GsonBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, Gson is strict and only accepts JSON as specified by
|
||||||
|
* <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. This option makes the parser
|
||||||
|
* liberal in what it accepts.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @see JsonReader#setLenient(boolean)
|
||||||
|
*/
|
||||||
|
public GsonBuilder setLenient() {
|
||||||
|
lenient = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default, Gson escapes HTML characters such as < > etc. Use this option to configure
|
* By default, Gson escapes HTML characters such as < > etc. Use this option to configure
|
||||||
* Gson to pass-through HTML characters as is.
|
* Gson to pass-through HTML characters as is.
|
||||||
@ -544,7 +567,7 @@ public final class GsonBuilder {
|
|||||||
|
|
||||||
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
|
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
|
||||||
serializeNulls, complexMapKeySerialization,
|
serializeNulls, complexMapKeySerialization,
|
||||||
generateNonExecutableJson, escapeHtmlChars, prettyPrinting,
|
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
|
||||||
serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
|
serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ public class JsonReader implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure this parser to be be liberal in what it accepts. By default,
|
* Configure this parser to be liberal in what it accepts. By default,
|
||||||
* this parser is strict and only accepts JSON as specified by <a
|
* this parser is strict and only accepts JSON as specified by <a
|
||||||
* href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. Setting the
|
* href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. Setting the
|
||||||
* parser to lenient causes it to ignore the following syntax errors:
|
* parser to lenient causes it to ignore the following syntax errors:
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Gson Authors
|
||||||
|
*
|
||||||
|
* 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.google.gson.functional;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import java.util.List;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functional tests for leniency option.
|
||||||
|
*/
|
||||||
|
public class LeniencyTest extends TestCase {
|
||||||
|
|
||||||
|
private Gson gson;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
gson = new GsonBuilder().setLenient().create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLenientFromJson() {
|
||||||
|
List<String> json = gson.fromJson(""
|
||||||
|
+ "[ # One!\n"
|
||||||
|
+ " 'Hi' #Element!\n"
|
||||||
|
+ "] # Array!", new TypeToken<List<String>>() {}.getType());
|
||||||
|
assertEquals(singletonList("Hi"), json);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user