How to escape json strings in freemarker
Solution 1
You're looking for the ?js_string
operator.
{
"field1" : "${response.value1?js_string}",
"field2" : "${response.value2?js_string}"
}
That will take care of escaping quotes, backslashes, et. al in order to make your JS happy.
Edit: I just saw that they introduced a ?json_string
operator in Freemarker 2.3.19. See here for exactly how it works. And there was much rejoicing...
Solution 2
Use a FreeMarker macro to combine all of the answers above, while making the template more readable and maintainable:
<#macro json_string string>${string?js_string?replace("\\'", "\'")?replace("\\>", ">")}</#macro>
{
"field1" : "<@json_string "${response.value1}"/>",
"field2" : "<@json_string "${response.value2}"/>"
}
If you want to reuse the macro in multiple templates, put it in its own file and include the file instead of duplicating the macro:
<#include "/path/to/macro.ftl">
Related videos on Youtube
![Skurpi](https://i.stack.imgur.com/Ob4cz.jpg?s=256&g=1)
Skurpi
Updated on July 09, 2022Comments
-
Skurpi almost 2 years
We are building a restful api using Spring MVC and freemarker as the templating language. We have chosen to build json responses in the freemarker
Example freemarker.ftl:
{ "field1" : "${response.value1}", "field2" : "${response.value2}" }
We get a problem when the strings in the values contain quotation marks (or any of the other characters in the JSON syntax).
The question: How can I escape these strings using freemarker?
We have looked at
?xml
or?html
but they do not cover all relevant characters (such as\
).EDIT:
?js_string
will escape the string to comform with JavaScript. And since JSON is based on JavaScript (JavaScript Object Notation), it will work.EDIT2: In case a single-quote pops up,
?js_string
will escape it which again leads to invalid JSON. The hotfix for it is:${variable?js_string?replace("\\'", "\'")}
and if you really want to be picky:
${variable?js_string?replace("\\'", "\'")?replace("\\>",">")}
Alternatively if you use Spring: http://www.springsurf.org/sites/1.0.0.M3/spring-webscripts/spring-webscripts-documentation/reference/html-single/index.html#js-api-index-org.springframework.extensions.webscripts.json.jsonutils
-
Stefan Haberl over 10 years+1 for the Spring alternative
-
-
Skurpi about 13 yearsWhats the advantage to ?js_string over ?j_string in this case?
-
Waldheinz about 13 years@Skurpi The advantage is that
js_string
does the necessary escaping whilej_string
does not. -
Skurpi about 13 years@Waldheinz & @stevevls Thank you!
-
Skurpi almost 13 years@Waldheinz @stevevls It seems it does not work entirely. See the following example: { "companyName" : "Rehabshopen AB, Göran Sjödén\'s" , "companyText" : "Vi säljer träning, sjukvård, hygienartiklar & ortoser. Uthyrning och försäljning av rullstolar &..." } If you run it through a validator it will fail, and the string has been ?js_string escaped. jsonformatter.curiousconcept.com/#jsonformatter
-
stevevls almost 13 years@Skurpi I see...it doesn't like the escaped single quote. Try this to get rid of the backslashes on the single quote :
${variable?js_string?replace('\\'', '\'')}
-
Skurpi almost 13 yearsIt seems risky to try to fix individual problems like that. I'd prefer an "automated" way to handle this, since there might be some other characters that it'll escape that might fail.
-
Skurpi almost 13 years@stevevls it should be: ${variable?js_string?replace("\\'", "\'")} But excellent!
-
stevevls almost 13 years@Skurpi Agreed that a built-in would be the best way to go. Hopefully they'll put one in the next version of Freemarker!
-
Skurpi over 12 yearsThis is actually what we did, but we put some extra functionality in it which we had use for: <#macro hazStringContent content> <#if content?has_content && content != "">"${content?js_string?replace("\\'", "\'")?replace("\\>",">")}"<#else>null</#if> </#macro>