Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Clojure: Writing JSON to a File

DZone's Guide to

Clojure: Writing JSON to a File

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

As I mentioned in an earlier post I’ve been transforming Clojure hash’s into JSON strings using data.json but ran into trouble while trying to parse a hash which contained a Joda Time DateTime instance.

The date in question was constructed like this:

(ns json-date-example
  (:require [clj-time.format :as f])
  (:require [clojure.data.json :as json]))
 
(defn as-date [date-field]
  (f/parse (f/formatter "dd MMM YYYY") date-field ))
 
(def my-date 
  (as-date "18 Mar 2012"))

And when I tried to convert a hash containing that object into a string I got the following exception:

> (json/write-str {:date my-date)})
 
java.lang.Exception: Don't know how to write JSON of class org.joda.time.DateTime
 at clojure.data.json$write_generic.invoke (json.clj:367)
    clojure.data.json$eval2818$fn__2819$G__2809__2826.invoke (json.clj:284)
    clojure.data.json$write_object.invoke (json.clj:333)
    clojure.data.json$eval2818$fn__2819$G__2809__2826.invoke (json.clj:284)
    clojure.data.json$write.doInvoke (json.clj:450)
    clojure.lang.RestFn.invoke (RestFn.java:425)

Luckily it’s quite easy to get around this by passing a function to write-str that converts the DateTime into a string representation before writing that part of the hash to a string.

The function looks like this:

(defn as-date-string [date]
  (f/unparse (f/formatter "dd MMM YYYY") date))
 
(defn date-aware-value-writer [key value] 
  (if (= key :date) (as-date-string value) value))

And we make use of the writer like so:

> (json/write-str {:date my-date} :value-fn date-aware-value-writer)
"{\"date\":\"18 Mar 2012\"}"

If we want to read that string back again and reify our date we create a reader function which converts a string into a DateTime. The as-date function from the beginning of this post does exactly what we want so we’ll use that:

(defn date-aware-value-reader [key value] 
  (if (= key :date) (as-date value) value))

We can then pass the reader as an argument to read-str:

> (json/read-str "{\"date\":\"18 Mar 2012\"}" :value-fn date-aware-value-reader :key-fn keyword)
{:date #<DateTime 2012-03-18T00:00:00.000Z>}

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:

Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}