ppp456878
ppp456878

Reputation: 155

How to convert Java String to EDN object?

In Clojure, I am using 'generate-string' function of cheshire (https://github.com/dakrone/cheshire) library to convert EDN to JSON.

It works fine if I call it directly using EDN data in Clojure i.e.

(defn generate-json-string
  (generate-string {:foo "bar" :baz {:eggplant [1 2 3]} :sesion nil} {:pretty true})
)

Output =>
{
  "foo": "bar",
  "baz": {
    "eggplant": [1,2,3]
  },
  "sesion": null
}

But it wont work if I call above function from Java and pass above same content in the form of Java String to it

(defn generate-json-string [content]
  (generate-string content {:pretty true})
)

Output => 
"{:foo \"bar\" :baz {:eggplant [1 2 3]} :session nil}"

How can I fix this?

Upvotes: 2

Views: 981

Answers (2)

Alan Thompson
Alan Thompson

Reputation: 29958

The following shows how to read/write data into either a JSON string or an EDN string.

Note that both JSON & EDN are string serialization formats, although Clojure literal data structures are often (sloppily) referred to as "EDN data" of just "EDN", even though EDN technically means the string representation.

Also, note that clojure.tools.reader.edn is the best (safest) way to convert an EDN string into a Clojure data structure.

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [clojure.tools.reader.edn :as edn]
    [tupelo.core :as t]
    [tupelo.string :as ts] ))

(def data
  "A clojure data literal"
  {:a "hello" :b {:c [1 2 3]}})

(dotest
  (let [json-str  (t/edn->json data) ; shortcut to Cheshire
        from-json (t/json->edn json-str) ; shortcut to Cheshire

        edn-str   (pr-str data) ; convert Clojure data structure => EDN string
        ; Using clojure.tools.reader.edn is the newest & safest way to
        ; read in an EDN string => data structure
        from-edn  (edn/read-string edn-str)]

    ; Convert all double-quotes to single-quotes for ease of comparison
    ; with string literal (no escapes needed)
    (is= (ts/quotes->single json-str) "{'a':'hello','b':{'c':[1,2,3]}}")
    (is= (ts/quotes->single edn-str)  "{:a 'hello', :b {:c [1 2 3]}}")

    ; If we don't convert to single quotes, we get a messier escaped
    ; string literals with escape chars '\'
    (is-nonblank= json-str "{\"a\":\"hello\",\"b\":{\"c\":[1,2,3]}}")
    (is-nonblank= edn-str   "{:a   \"hello\", :b   {:c    [1 2 3]}}")

    ; Converting either EDN or JSON string into clojure data yields the same result
    (is= data
      from-json
      from-edn)))

Upvotes: 2

ppp456878
ppp456878

Reputation: 155

I was able to solve this by using edn/read-string function.

(defn generate-json-string [content]
  (generate-string (edn/read-string content) {:pretty true})
)

Upvotes: 2

Related Questions