gson library heavily depends on reflection and so it's hard to keep the support for Scala. Use json4s or circe library instead.
Allows to use Scala and Java 8 types with gson library.
Supported types:
java.time.Instant
java.time.Duration
scala.concurrent.duration.Duration
java.util.Optional
scala.Option
scala.Seq
<dependency>
<groupId>cz.augi.gsonscala</groupId>
<artifactId>gson-scala_2.12</artifactId>
<version>$latestVersion</version>
</dependency>
compile "cz.augi.gsonscala:gson-scala_2.12:$latestVersion"
import cz.augi.gsonscala._
val gson = new GsonBuilder()
.registerMillisDurationConverters() // registers for Duration classes expecting millis in integer values
.registerUnixMillisInstantConverter() // registers for Instant expecting Unix millis in integer values
.registerBasicConverters() // registers for Optional, Option and Seq
.create()
The registerBasicConverters``must be called as the last method before the
create` method.
Alternatively, these methods can be used for registrations:
registerSecondsDurationConverters
- expects durations in secondsregisterStringDurationConverters
registerUnixSecondsInstantConverter
- expects time in Unix timestamp (seconds)registerStringInstantConverter
- expects time in ISO format
You can also cherry-pick some of converters as shown here.
Please note that
registerBasicConverters
also registers NonNullTypeAdapterFactory - it's required because the default object deserializer doesn't call deserializer of a field if the value is not even present in the json.
As gson library targets Java 6, it doesn't support Java 8 type out of the box. There are several libraries that add support
for Optional
type but most of them is not able to handle missing value correctly.
For example gson-java8-datatype looked promising but
it has too simple tests.
E.g. if you have a class with Optional
field then the deserialized object contains null
instead of Optional.empty()
.
The problem is that gson
by default doesn't write null
values. So the read
method of TypeAdapter
is not even called for missing value
and the field of deserialized object has null
value. Tests of gson-java8-datatype
are passing because null
value is written if it's top-level object.