   (if (string? body)
     body
     (slurp body)))
+
+(defn soft-reference->json!
+  "Given a soft reference object and a Cheshire JSON generator, write the
+  data stored in the soft reference to the generator as a JSON string.
+
+  Note, however, that sometimes the value is not a soft reference, but rather
+  a raw value from the response. In that case, we need to skip the object
+  conversion, and just do the realization."
+  [obj json-generator]
+  (let [data @(if (isa? obj SoftReference)
+                (.get obj)
+                obj)
+        data-str (json/generate-string data)]
+    (log/trace "Encoder got data: " data)
+    (.writeString json-generator data-str)))
+
+;; This adds support for JSON-encoding the data cached in a SoftReference.
+(json-gen/add-encoder SoftReference soft-reference->json!)
 
 (defn parse-json-body
   [body]


(def json-handler #(client-handler % error-handler parse-json-body))
(def xml-handler #(client-handler % error-handler parse-xml-body))

  by single use or composition."
  (:require
   [cheshire.core :as json]
   [cheshire.generate :as json-gen]
   [clojure.data.xml :as xml]
   [clojure.string :as string]
   [cmr.exchange.common.results.errors :as errors]
   [ring.util.http-response :as response]
   [taoensso.timbre :as log]
   [xml-in.core :as xml-in])
  (:import
    (java.lang.ref SoftReference))
  (:refer-clojure :exclude [error-handler]))

(defn stream->str
