001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.http.converter.json;
018
019import java.text.SimpleDateFormat;
020
021import com.google.gson.Gson;
022import com.google.gson.GsonBuilder;
023
024import org.springframework.beans.factory.FactoryBean;
025import org.springframework.beans.factory.InitializingBean;
026import org.springframework.lang.Nullable;
027
028/**
029 * A {@link FactoryBean} for creating a Google Gson 2.x {@link Gson} instance.
030 *
031 * @author Roy Clarkson
032 * @author Juergen Hoeller
033 * @since 4.1
034 */
035public class GsonFactoryBean implements FactoryBean<Gson>, InitializingBean {
036
037        private boolean base64EncodeByteArrays = false;
038
039        private boolean serializeNulls = false;
040
041        private boolean prettyPrinting = false;
042
043        private boolean disableHtmlEscaping = false;
044
045        @Nullable
046        private String dateFormatPattern;
047
048        @Nullable
049        private Gson gson;
050
051
052        /**
053         * Whether to Base64-encode {@code byte[]} properties when reading and
054         * writing JSON.
055         * <p>When set to {@code true}, a custom {@link com.google.gson.TypeAdapter} will be
056         * registered via {@link GsonBuilder#registerTypeHierarchyAdapter(Class, Object)}
057         * which serializes a {@code byte[]} property to and from a Base64-encoded String
058         * instead of a JSON array.
059         * @see GsonBuilderUtils#gsonBuilderWithBase64EncodedByteArrays()
060         */
061        public void setBase64EncodeByteArrays(boolean base64EncodeByteArrays) {
062                this.base64EncodeByteArrays = base64EncodeByteArrays;
063        }
064
065        /**
066         * Whether to use the {@link GsonBuilder#serializeNulls()} option when writing
067         * JSON. This is a shortcut for setting up a {@code Gson} as follows:
068         * <pre class="code">
069         * new GsonBuilder().serializeNulls().create();
070         * </pre>
071         */
072        public void setSerializeNulls(boolean serializeNulls) {
073                this.serializeNulls = serializeNulls;
074        }
075
076        /**
077         * Whether to use the {@link GsonBuilder#setPrettyPrinting()} when writing
078         * JSON. This is a shortcut for setting up a {@code Gson} as follows:
079         * <pre class="code">
080         * new GsonBuilder().setPrettyPrinting().create();
081         * </pre>
082         */
083        public void setPrettyPrinting(boolean prettyPrinting) {
084                this.prettyPrinting = prettyPrinting;
085        }
086
087        /**
088         * Whether to use the {@link GsonBuilder#disableHtmlEscaping()} when writing
089         * JSON. Set to {@code true} to disable HTML escaping in JSON. This is a
090         * shortcut for setting up a {@code Gson} as follows:
091         * <pre class="code">
092         * new GsonBuilder().disableHtmlEscaping().create();
093         * </pre>
094         */
095        public void setDisableHtmlEscaping(boolean disableHtmlEscaping) {
096                this.disableHtmlEscaping = disableHtmlEscaping;
097        }
098
099        /**
100         * Define the date/time format with a {@link SimpleDateFormat}-style pattern.
101         * This is a shortcut for setting up a {@code Gson} as follows:
102         * <pre class="code">
103         * new GsonBuilder().setDateFormat(dateFormatPattern).create();
104         * </pre>
105         */
106        public void setDateFormatPattern(String dateFormatPattern) {
107                this.dateFormatPattern = dateFormatPattern;
108        }
109
110
111        @Override
112        public void afterPropertiesSet() {
113                GsonBuilder builder = (this.base64EncodeByteArrays ?
114                                GsonBuilderUtils.gsonBuilderWithBase64EncodedByteArrays() : new GsonBuilder());
115                if (this.serializeNulls) {
116                        builder.serializeNulls();
117                }
118                if (this.prettyPrinting) {
119                        builder.setPrettyPrinting();
120                }
121                if (this.disableHtmlEscaping) {
122                        builder.disableHtmlEscaping();
123                }
124                if (this.dateFormatPattern != null) {
125                        builder.setDateFormat(this.dateFormatPattern);
126                }
127                this.gson = builder.create();
128        }
129
130
131        /**
132         * Return the created Gson instance.
133         */
134        @Override
135        @Nullable
136        public Gson getObject() {
137                return this.gson;
138        }
139
140        @Override
141        public Class<?> getObjectType() {
142                return Gson.class;
143        }
144
145        @Override
146        public boolean isSingleton() {
147                return true;
148        }
149
150}