6

With the following app:

; src/webapp/core.clj
(ns webapp.core
  (:require [compojure.core :refer [defroutes GET]]
            [ring.middleware.json :as mid-json]
            [clj-time.jdbc]))

(defn foo [request]
  {:body {:now (org.joda.time.DateTime/now)}})

(defroutes routes
  (GET "/foo" [] foo))

(def app
  (-> routes
      (mid-json/wrap-json-response)))

Hitting the /foo endpoint gives me this error:

com.fasterxml.jackson.core.JsonGenerationException: Cannot JSON encode object of class: class org.joda.time.DateTime: 2017-10-21T03:38:16.207Z

Is there a simple way to get ring-json to encode the DateTime object? Do I have to write my own middleware to convert it to e.g. a string first? If so, how would I do that? (I've never written ring middleware before).

My project.clj has these dependencies FYI:

[[org.clojure/clojure "1.8.0"]
 [org.clojure/java.jdbc "0.6.1"]
 [ring/ring-jetty-adapter "1.4.0"]
 [compojure "1.4.0"]
 [ring/ring-json "0.4.0"]
 [clj-time "0.14.0"]]
Jacob O'Bryant
  • 311
  • 2
  • 10

2 Answers2

10

If you're using Cheshire to generate JSON, you can extend its protocol to handle serialization then it should "just work":

(extend-protocol cheshire.generate/JSONable
  org.joda.time.DateTime
  (to-json [dt gen]
    (cheshire.generate/write-string gen (str dt))))
Taylor Wood
  • 15,886
  • 1
  • 20
  • 37
0

Additionally, the following modification made it work for projects that are using the time library tick.alpha.api. I was getting the error

#error {:cause Cannot JSON encode object of class:
 class java.time.Instant: 2019-10-23T00:31:40.668Z
 :via
 [{:type com.fasterxml.jackson.core.JsonGenerationException
   :message Cannot JSON encode object of class:
 class java.time.Instant: 2019-10-23T00:31:40.668Z
   :at [cheshire.generate$generate invokeStatic generate.clj 152]}]

Implementing the following in the file db/core.clj fixed the issue for me.

(extend-protocol cheshire.generate/JSONable
  java.time.Instant
  (to-json [dt gen]
    (cheshire.generate/write-string gen (str dt))))
CambodianCoder
  • 467
  • 4
  • 14