7

I have a case class with many members, two of which are non-primitive:

import com.twitter.util.Duration
case class Foo(
  a: Int,
  b: Int,
  ...,
  y: Int,
  z: Int,
  timeoutSeconds: Duration,
  runtimeMinutes: Duration)

I'd like to deserialize the following JSON into an instance of this case class:

{
  "a": 1,
  "b": 2,
  // ...
  "y": 42,
  "z": 43,
  "timeoutSeconds": 30,
  "runtimeMinutes": 12,
}

Normally, I would just write json.extract[Foo]. However, I get an obvious MappingException with that because of timeoutSeconds and runtimeMinutes.

I've looked at FieldSerializer, which allows field transforms on the AST. However, it's insufficient because it only allows AST transforms.

I've also looked at extending CustomSerializer[Duration], but there's no way to introspect which JSON key is being dealt with (timeoutSeconds or runtimeMinutes).

I could also try extending CustomSerializer[Foo], but then I will have a lot of boilerplate code for extracting values for a, b, ..., z.

Ideally, I need something that takes PartialFunction[JField, T] as a deserializer so that I could just write:

{
  case ("timeoutSeconds", JInt(timeout) => timeout.seconds
  case ("runtimeMinutes", JInt(runtime) => runtime.minutes
}

and rely on case class deserialization for the remaining parameters. Is such a construction possible in json4s?

Note this is similar to Combining type and field serializers, except I additionally want the type deserialization to differ based on the JSON key.

Community
  • 1
  • 1
kenrose
  • 186
  • 1
  • 5
  • As a workaround, you could serialize all your `Duration`s in seconds then update the `runtimeMinutes` field. – Dimitri Nov 29 '14 at 14:14
  • 1
    i.e., Add a CustomSerializer[Duration] that always does seconds, then `orig.copy(runtimeMinutes = orig.runtimeMinutes / 60)`. That would work, but is a little hacky. Thanks for the suggestion though. – kenrose Nov 30 '14 at 00:06

1 Answers1

0

Using Json.NET

string json = @"{

"a": 1, "b": 2, // ... "y": 42, "z": 43, "timeoutSeconds": 30, "runtimeMinutes": 12, }";

BlogSites bsObj = JsonConvert.DeserializeObject<BlogSites>(json);  

Response.Write(bsObj.Name);  
Prabha Rajan
  • 70
  • 1
  • 4