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 {
|
||||
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";
|
||||
|
||||
@ -124,6 +130,7 @@ public final class Gson {
|
||||
private final boolean htmlSafe;
|
||||
private final boolean generateNonExecutableJson;
|
||||
private final boolean prettyPrinting;
|
||||
private final boolean lenient;
|
||||
|
||||
final JsonDeserializationContext deserializationContext = new JsonDeserializationContext() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -177,15 +184,16 @@ public final class Gson {
|
||||
*/
|
||||
public Gson() {
|
||||
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
|
||||
Collections.<Type, InstanceCreator<?>>emptyMap(), false, false, DEFAULT_JSON_NON_EXECUTABLE,
|
||||
true, false, false, LongSerializationPolicy.DEFAULT,
|
||||
Collections.<TypeAdapterFactory>emptyList());
|
||||
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
|
||||
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
|
||||
DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
|
||||
LongSerializationPolicy.DEFAULT, Collections.<TypeAdapterFactory>emptyList());
|
||||
}
|
||||
|
||||
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
|
||||
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
|
||||
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
|
||||
boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
|
||||
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
|
||||
LongSerializationPolicy longSerializationPolicy,
|
||||
List<TypeAdapterFactory> typeAdapterFactories) {
|
||||
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
||||
@ -193,6 +201,7 @@ public final class Gson {
|
||||
this.generateNonExecutableJson = generateNonExecutableGson;
|
||||
this.htmlSafe = htmlSafe;
|
||||
this.prettyPrinting = prettyPrinting;
|
||||
this.lenient = lenient;
|
||||
|
||||
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||
|
||||
@ -704,6 +713,15 @@ public final class Gson {
|
||||
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}.
|
||||
* @throws JsonIOException if there was a problem writing to the writer
|
||||
@ -795,7 +813,7 @@ public final class Gson {
|
||||
* @since 1.2
|
||||
*/
|
||||
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);
|
||||
assertFullConsumption(object, jsonReader);
|
||||
return Primitives.wrap(classOfT).cast(object);
|
||||
@ -822,7 +840,7 @@ public final class Gson {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
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);
|
||||
assertFullConsumption(object, jsonReader);
|
||||
return object;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Timestamp;
|
||||
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.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
|
||||
* 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>();
|
||||
/** tree-style hierarchy factories. These come after factories for backwards compatibility. */
|
||||
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
|
||||
private boolean serializeNulls;
|
||||
private boolean serializeNulls = DEFAULT_SERIALIZE_NULLS;
|
||||
private String datePattern;
|
||||
private int dateStyle = DateFormat.DEFAULT;
|
||||
private int timeStyle = DateFormat.DEFAULT;
|
||||
private boolean complexMapKeySerialization;
|
||||
private boolean serializeSpecialFloatingPointValues;
|
||||
private boolean escapeHtmlChars = true;
|
||||
private boolean prettyPrinting;
|
||||
private boolean generateNonExecutableJson;
|
||||
private boolean complexMapKeySerialization = DEFAULT_COMPLEX_MAP_KEYS;
|
||||
private boolean serializeSpecialFloatingPointValues = DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
||||
private boolean escapeHtmlChars = DEFAULT_ESCAPE_HTML;
|
||||
private boolean prettyPrinting = DEFAULT_PRETTY_PRINT;
|
||||
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
|
||||
@ -351,6 +361,19 @@ public final class GsonBuilder {
|
||||
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
|
||||
* Gson to pass-through HTML characters as is.
|
||||
@ -544,7 +567,7 @@ public final class GsonBuilder {
|
||||
|
||||
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
|
||||
serializeNulls, complexMapKeySerialization,
|
||||
generateNonExecutableJson, escapeHtmlChars, prettyPrinting,
|
||||
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
|
||||
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
|
||||
* href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. Setting the
|
||||
* 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