当Json序列化和反序列化操作时需要创建Gson对象来帮助完成,而创建Gson的方式有两种方式
方式1:直接创建Gson对象,然后对json字符串进行序列化和反序列化操作
public static class ExposeBean {
public String firstName;
public String lastName;
public String emailAddress;
public String password;
public ExposeBean(String firstName, String lastName, String emailAddress, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.emailAddress = emailAddress;
this.password = password;
}
@Override
public String toString() {
return "ExposeBean{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", emailAddress='" + emailAddress + '\'' +
", password='" + password + '\'' +
'}';
}
public static void main(String[] args) {
val data= GsonAnnotation.ExposeBean("v1", "v2", "email","密码");
val gson= Gson();
val json= gson.toJson(data);
System.out.println(json);
}
}
打印信息
{ "emailAddress":"email", "firstName":"v1", "lastName":"v2",
"password":"密码"}
方式2:通过GsonBuilder来构建Gson对象,然后对json字符串进行序列化和反序列化操作
public static class ExposeBean {
//参与序列化和反序列化
@Expose
public String firstName;
//参与序列化 但不参与反序列化
@Expose(serialize = true, deserialize = true)
public String lastName;
//不参与序列化和反序列化
@Expose(serialize = false, deserialize = true)
public String emailAddress;
//不参与序列化和反序列化
public String password;
public ExposeBean(String firstName, String lastName, String emailAddress, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.emailAddress = emailAddress;
this.password = password;
}
@Override
public String toString() {
return "ExposeBean{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", emailAddress='" + emailAddress + '\'' +
", password='" + password + '\'' +
'}';
}
public static void main(String[] args) {
val data= GsonAnnotation.ExposeBean("v1", "v2", "email","密码");
val gson= GsonBuilder()
.setPrettyPrinting()//设置格式化打印
.excludeFieldsWithoutExposeAnnotation()//启动Expose注解的使用 若需要使用expose注解 需要调用该方法才能生效
.create();
val json= gson.toJson(data);
System.out.println(json);
}
}
打印信息
{
"firstName":"v1",
"lastName":"v2"
}
在通过Gson解析json过程中一般是直接通过创建Gson对象来实现json的序列化和反序列化,但是若需要对Gson做一些配置,就需要通过GsonBuilder来构建gson,那么老看看GsonBuilder做了哪些操作。
public final class GsonBuilder {
//过滤器
private Excluder excluder = Excluder.DEFAULT;
//序列化策略
private LongSerializationPolicy longSerializationPolicy = LongSerializationPolicy.DEFAULT;
//命名策略
private FieldNamingStrategy fieldNamingPolicy = FieldNamingPolicy.IDENTITY;
//map集合 key:class对应的type value:InstanceCreator 用于根据type来创建java bean
private final Map<Type, InstanceCreator<?>> instanceCreators
= new HashMap<Type, InstanceCreator<?>>();
//TypeAdapter的工厂集合
private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
/** 样式层次工厂。这些都是继工厂之后的向后兼容性 */
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
//标识符 null值是否要序列化
private boolean serializeNulls = DEFAULT_SERIALIZE_NULLS;
//日期模式
private String datePattern;
private int dateStyle = DateFormat.DEFAULT;
private int timeStyle = DateFormat.DEFAULT;
//是否需要复杂的映射键序列化
private boolean complexMapKeySerialization = DEFAULT_COMPLEX_MAP_KEYS;
private boolean serializeSpecialFloatingPointValues = DEFAULT_SPECIALIZE_FLOAT_VALUES;
//是否使用Gson转义HTML字符 默认为true
private boolean escapeHtmlChars = DEFAULT_ESCAPE_HTML;
//标识符 是否需要格式化打印
private boolean prettyPrinting = DEFAULT_PRETTY_PRINT;
//标识符 是否不执行过滤 默认false
private boolean generateNonExecutableJson = DEFAULT_JSON_NON_EXECUTABLE;
//标识符 是否是宽容政策 默认false
private boolean lenient = DEFAULT_LENIENT;
/**
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
* settings. GsonBuilder follows the builder pattern, and it is typically used by first
* invoking various configuration methods to set desired options, and finally calling
* {@link #create()}.
*/
public GsonBuilder() {
}
/**
* Constructs a GsonBuilder instance from a Gson instance. The newly constructed GsonBuilder
* has the same configuration as the previously built Gson instance.
*
* @param gson the gson instance whose configuration should by applied to a new GsonBuilder.
*/
GsonBuilder(Gson gson) {
this.excluder = gson.excluder;
this.fieldNamingPolicy = gson.fieldNamingStrategy;
this.instanceCreators.putAll(gson.instanceCreators);
this.serializeNulls = gson.serializeNulls;
this.complexMapKeySerialization = gson.complexMapKeySerialization;
this.generateNonExecutableJson = gson.generateNonExecutableJson;
this.escapeHtmlChars = gson.htmlSafe;
this.prettyPrinting = gson.prettyPrinting;
this.lenient = gson.lenient;
this.serializeSpecialFloatingPointValues = gson.serializeSpecialFloatingPointValues;
this.longSerializationPolicy = gson.longSerializationPolicy;
this.datePattern = gson.datePattern;
this.dateStyle = gson.dateStyle;
this.timeStyle = gson.timeStyle;
this.factories.addAll(gson.builderFactories);
this.hierarchyFactories.addAll(gson.builderHierarchyFactories);
}
/**
* 配置Gson以启用版本支持
* 当我们设置了版本后 它会和since/until注解上设置的版本进行比较,若不符合将会被忽略,不被进行序列化和反序列化
*
* @param ignoreVersionsAfter
* @return
*/
public GsonBuilder setVersion(double ignoreVersionsAfter) {
excluder = excluder.withVersion(ignoreVersionsAfter);
return this;
}
/**
* 配置Gson排除所有具有指定修饰符的类字段。默认情况下,Gson将排除所有标记为transient或static的字段。此方法将覆盖该行为
* @param modifiers
* @return
*/
public GsonBuilder excludeFieldsWithModifiers(int... modifiers) {
excluder = excluder.withModifiers(modifiers);
return this;
}
/**
* 通过在生成的JSON前面加上一些特殊的文本,使输出JSON在Javascript中不可执行。这可以防止第三方网站通过脚本来源进行攻击
* <a href="http://code.google.com/p/google-gson/issues/detail?id=42">
* @return
*/
public GsonBuilder generateNonExecutableJson() {
this.generateNonExecutableJson = true;
return this;
}
/**
* 允许属性执行Expose注解 默认是不允许的 当Java bean使用了Expose注解需要调用该方法
* @return
*/
public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
excluder = excluder.excludeFieldsWithoutExposeAnnotation();
return this;
}
/**
* 是否允许序列化空值
* @return
*/
public GsonBuilder serializeNulls() {
this.serializeNulls = true;
return this;
}
/**
* Enabling this feature will only change the serialized form if the map key is
* a complex type (i.e. non-primitive) in its <strong>serialized</strong> JSON
* form. The default implementation of map serialization uses {@code toString()}
* on the key; however, when this is called then one of the following cases
* apply:
*
* <h3>Maps as JSON objects</h3>
* For this case, assume that a type adapter is registered to serialize and
* deserialize some {@code Point} class, which contains an x and y coordinate,
* to/from the JSON Primitive string value {@code "(x,y)"}. The Java map would
* then be serialized as a {@link JsonObject}.
*
* <p>Below is an example:
* <pre> {@code
* Gson gson = new GsonBuilder()
* .register(Point.class, new MyPointTypeAdapter())
* .enableComplexMapKeySerialization()
* .create();
*
* Map<Point, String> original = new LinkedHashMap<Point, String>();
* original.put(new Point(5, 6), "a");
* original.put(new Point(8, 8), "b");
* System.out.println(gson.toJson(original, type));
* }</pre>
* The above code prints this JSON object:<pre> {@code
* {
* "(5,6)": "a",
* "(8,8)": "b"
* }
* }</pre>
*
* <h3>Maps as JSON arrays</h3>
* For this case, assume that a type adapter was NOT registered for some
* {@code Point} class, but rather the default Gson serialization is applied.
* In this case, some {@code new Point(2,3)} would serialize as {@code
* {"x":2,"y":5}}.
*
* <p>Given the assumption above, a {@code Map<Point, String>} will be
* serialize as an array of arrays (can be viewed as an entry set of pairs).
*
* <p>Below is an example of serializing complex types as JSON arrays:
* <pre> {@code
* Gson gson = new GsonBuilder()
* .enableComplexMapKeySerialization()
* .create();
*
* Map<Point, String> original = new LinkedHashMap<Point, String>();
* original.put(new Point(5, 6), "a");
* original.put(new Point(8, 8), "b");
* System.out.println(gson.toJson(original, type));
* }
*
* The JSON output would look as follows:
* <pre> {@code
* [
* [
* {
* "x": 5,
* "y": 6
* },
* "a"
* ],
* [
* {
* "x": 8,
* "y": 8
* },
* "b"
* ]
* ]
* }</pre>
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
*/
/**
* 如果map key是一个serialized JSON形式的复杂类型(即非原始类型),启用该功能将只会改变序列化的形式。
* 映射序列化的默认实现在键上使用{@code toString()};然而,当这被调用时,下列情况之一适用:
* 映射为JSON对象
* *对于本例,假设类型适配器已注册为序列化和
* 反序列化某个包含x和y坐标的{@code Point}类,
* 从JSON原始字符串值{@code "(x,y)"}。Java映射
* 然后序列化为{@link JsonObject}
* *
* @return
*/
public GsonBuilder enableComplexMapKeySerialization() {
complexMapKeySerialization = true;
return this;
}
/**
* Configures Gson to exclude inner classes during serialization.
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.3
*/
public GsonBuilder disableInnerClassSerialization() {
excluder = excluder.disableInnerClassSerialization();
return this;
}
/**
* Configures Gson to apply a specific serialization policy for {@code Long} and {@code long}
* objects.
*
* @param serializationPolicy the particular policy to use for serializing longs.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.3
*/
public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
this.longSerializationPolicy = serializationPolicy;
return this;
}
/**
* 配置Gson在序列化和反序列化过程中对对象的字段应用特定的命名策略。
* @param namingConvention
* @return
*/
public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
this.fieldNamingPolicy = namingConvention;
return this;
}
/**
* 配置Gson在序列化和反序列化过程中对对象的字段应用特定的命名策略
* @param fieldNamingStrategy
* @return
*/
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
this.fieldNamingPolicy = fieldNamingStrategy;
return this;
}
/**
* 设置自定义的过滤策略
* @param strategies
* @return
*/
public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
for (ExclusionStrategy strategy : strategies) {
excluder = excluder.withExclusionStrategy(strategy, true, true);
}
return this;
}
/**
* 配置Gson应用在序列化过程中传递的过滤策略
* @param strategy
* @return
*/
public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) {
excluder = excluder.withExclusionStrategy(strategy, true, false);
return this;
}
/**
* 配置Gson应用在反序列化过程中传递的过滤策略
* @param strategy
* @return
*/
public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) {
excluder = excluder.withExclusionStrategy(strategy, false, true);
return this;
}
/**
* 是否启动格式化打印信息
* @return
*/
public GsonBuilder setPrettyPrinting() {
prettyPrinting = true;
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;
}
/**
* 是否禁用Gson转义HTML字符 默认为true:Gson转义HTML字符 false:禁止Gson转义HTML字符
* @return
*/
public GsonBuilder disableHtmlEscaping() {
this.escapeHtmlChars = false;
return this;
}
/**
* Configures Gson to serialize {@code Date} objects according to the pattern provided. You can
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
* will be used to decide the serialization format.
*
* <p>The date format will be used to serialize and deserialize {@link java.util.Date}, {@link
* java.sql.Timestamp} and {@link java.sql.Date}.
*
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
* valid date and time patterns.</p>
*
* @param pattern the pattern that dates will be serialized/deserialized to/from
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.2
*/
public GsonBuilder setDateFormat(String pattern) {
// TODO(Joel): Make this fail fast if it is an invalid date format
this.datePattern = pattern;
return this;
}
/**
* 设置时间格式 用于确定日期适配器的格式
* @param style 日期样式
* @return
*/
public GsonBuilder setDateFormat(int style) {
this.dateStyle = style;
this.datePattern = null;
return this;
}
/**
* 设置时间格式 用于确定日期适配器的格式
* @param dateStyle 日期样式
* @param timeStyle 时间样式
* @return
*/
public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
this.dateStyle = dateStyle;
this.timeStyle = timeStyle;
this.datePattern = null;
return this;
}
/**
* 配置Gson自定义序列化或反序列化
* @param type java bean的class对象
* @param typeAdapter 可以是typeAdapter/InstanceCreator/JsonSerializer/JsonDeserializer
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?>
|| typeAdapter instanceof InstanceCreator<?>
|| typeAdapter instanceof TypeAdapter<?>);
if (typeAdapter instanceof InstanceCreator<?>) {
instanceCreators.put(type, (InstanceCreator) typeAdapter);
}
if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) {
TypeToken<?> typeToken = TypeToken.get(type);
factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
}
if (typeAdapter instanceof TypeAdapter<?>) {
factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
}
return this;
}
/**
* 为java bean或者java bean中的属性添加一个自定义TypeAdapter解析器工厂
* @param factory
* @return
*/
public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
factories.add(factory);
return this;
}
/**
* 配置Gson用于继承类型层次结构的自定义序列化或反序列化。
* 这个方法结合了{@link TypeAdapter}、{@link JsonSerializer}和{@link JsonDeserializer}的注册。
* 如果先前已为指定的类型层次结构注册了类型适配器,则会覆盖该适配器。如果类型适配器是为类型层次结构中的特定类型注册的,
* 那么将调用它,而不是为类型层次结构注册的适配器。
* @param baseType java bean的class对象
* @param typeAdapter 可以是typeAdapter/JsonSerializer/JsonDeserializer
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?>
|| typeAdapter instanceof TypeAdapter<?>);
if (typeAdapter instanceof JsonDeserializer || typeAdapter instanceof JsonSerializer) {
hierarchyFactories.add(TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
}
if (typeAdapter instanceof TypeAdapter<?>) {
factories.add(TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter));
}
return this;
}
/**
* 是否允许序列化双精度值(NaN, Infinity, -Infinity)
* 默认是不允许的序列化双进度值的 若是false,在解析json的过程中出现了会抛异常
* @return
*/
public GsonBuilder serializeSpecialFloatingPointValues() {
this.serializeSpecialFloatingPointValues = true;
return this;
}
/**
* 1.根据当前配置创建一个gson实例 可以多次调用
* 2.将注册的TypeAdapterFactory做为参数传递给Gson
* @return
*/
public Gson create() {
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(this.factories.size() + this.hierarchyFactories.size() + 3);
factories.addAll(this.factories);
Collections.reverse(factories);
List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>(this.hierarchyFactories);
Collections.reverse(hierarchyFactories);
factories.addAll(hierarchyFactories);
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
serializeNulls, complexMapKeySerialization,
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
serializeSpecialFloatingPointValues, longSerializationPolicy,
datePattern, dateStyle, timeStyle,
this.factories, this.hierarchyFactories, factories);
}
@SuppressWarnings("unchecked")
private void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
List<TypeAdapterFactory> factories) {
DefaultDateTypeAdapter dateTypeAdapter;
TypeAdapter<Timestamp> timestampTypeAdapter;
TypeAdapter<java.sql.Date> javaSqlDateTypeAdapter;
if (datePattern != null && !"".equals(datePattern.trim())) {
dateTypeAdapter = new DefaultDateTypeAdapter(Date.class, datePattern);
timestampTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(Timestamp.class, datePattern);
javaSqlDateTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(java.sql.Date.class, datePattern);
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
dateTypeAdapter = new DefaultDateTypeAdapter(Date.class, dateStyle, timeStyle);
timestampTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(Timestamp.class, dateStyle, timeStyle);
javaSqlDateTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(java.sql.Date.class, dateStyle, timeStyle);
} else {
return;
}
factories.add(TypeAdapters.newFactory(Date.class, dateTypeAdapter));
factories.add(TypeAdapters.newFactory(Timestamp.class, timestampTypeAdapter));
factories.add(TypeAdapters.newFactory(java.sql.Date.class, javaSqlDateTypeAdapter));
}
}
说明
GsonBuilder()
无参构造函数,主要创建GsonBuilder对象,当需要创建Gson对象时调用create()方法
GsonBuilder(Gson gson)
有参数构造函数。将gson的配置信息作为默认配置信息。当需要创建Gson对象时调用create()方法
create()
用于构建gson对象,将一些配置信息作为参数传递了Gson,这样就相当于对Gson的一些配置进行了修改
setVersion(double ignoreVersionsAfter)
设置版本信息到过滤器中,当属性设置了Until/Since注解后,会获取注解上的版本值,和设置的这个版本值进行比较,从而来判断属性是否可以进行序列化/反序列化.默认是-1,忽略版本过滤
excludeFieldsWithModifiers(int… modifiers)
配置属性增加了何种修饰符后在序列化/反序列化过程中会被过滤。默认情况下只对标记为transient或static的字段进行过滤
generateNonExecutableJson()
通过在生成的JSON前面加上一些特殊的文本,使输出JSON在Javascript中不可执行,这可以防止第三方网站通过脚本来源进行攻击
excludeFieldsWithoutExposeAnnotation()
允许属性执行Expose注解 默认是不允许的 当Java bean使用了Expose注解需要调用该方法才会生效
serializeNulls()
是否允许对null进行序列化,默认是不允许的。false:不允许 true:允许
setFieldNamingPolicy(FieldNamingPolicy namingConvention)
配置Gson在序列化和反序列化过程中对对象的字段应用特定的命名策略
setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy)
配置Gson在序列化和反序列化过程中对对象的字段应用特定的命名策略
setExclusionStrategies(ExclusionStrategy… strategies)
配置多个过滤策略
addSerializationExclusionStrategy(ExclusionStrategy strategy)
配置Gson应用在序列化过程中传递的过滤策略
addDeserializationExclusionStrategy(ExclusionStrategy strategy)
配置Gson应用在反序列化过程中传递的过滤策略
setPrettyPrinting()
是否启动格式化打印信息
disableHtmlEscaping()
是否禁用Gson转义HTML字符 默认为true:Gson转义HTML字符 false:禁止Gson转义HTML字符
**registerTypeAdapter(Type type, Object typeAdapter) **
配置Gson自定义序列化或反序列化. 参数type :java bean的class对象.参数typeAdapter :可以是typeAdapter/InstanceCreator/JsonSerializer/JsonDeserializer
registerTypeAdapterFactory(TypeAdapterFactory factory)
为java bean或者java bean中的属性添加一个自定义TypeAdapter解析器工厂.
registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter)
* 配置Gson用于继承类型层次结构的自定义序列化或反序列化。
* 这个方法结合了{@link TypeAdapter}、{@link JsonSerializer}和{@link JsonDeserializer}的注册。
* 如果先前已为指定的类型层次结构注册了类型适配器,则会覆盖该适配器。如果类型适配器是为类型层次结构中的特定类型注册的,
* 那么将调用它,而不是为类型层次结构注册的适配器。
* @param baseType java bean的class对象
* @param typeAdapter 可以是typeAdapter/JsonSerializer/JsonDeserializer
serializeSpecialFloatingPointValues()
是否允许序列化双精度值(NaN, Infinity, -Infinity) 默认是不允许的序列化双进度值的 若是false,在解析json的过程中出现了会抛异常
setDateFormat(int dateStyle, int timeStyle)
* 设置时间格式 用于确定日期适配器的格式
* @param dateStyle 日期样式
* @param timeStyle 时间样式