Ryan
Ryan

Reputation: 440

spring:escapeBody results in invalid JSON

I am attempting to escape a string in a JSP to return valid JSON on an AJAX call however the spring:escapeBody tag is not correctly escaping single quotes for JSON. Valid JSON should not escape single quotes.

<%@ page trimDirectiveWhitespaces="true" contentType="json/application"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
{
"status": "success",
"body" : "<spring:escapeBody javaScriptEscape="true"> 
           if you don't have "user" an account
           </spring:escapeBody>"
 }

so this code evaluates to:

{
"status": "success",
"body" : "if you don\'t have \"user\" an account"
 }

but valid JSON needs it to be:

{
"status": "success",
"body" : "if you don't have \"user\" an account"
 }

is there anyway I can not escape the single quote with the escapeBody tag? Or is there another tag I can use? maybe a JSTL function?

Upvotes: 2

Views: 2751

Answers (2)

Adriano
Adriano

Reputation: 20041

As pointed out by Ryan in the (very good) comments of Sotirios Delimanolis's answer:

So it seems like it's simply an implementation choice that is now leaving us with a standard that's not really consistently implemented... sigh

Anyway, here is a work around you can use to get your code working

<%@ page trimDirectiveWhitespaces="true" contentType="json/application"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%-- 
    [1] Removing the escape of the single quote character: jQuery's Ajax cannot handle it
            stackoverflow.com/questions/25491391/springescapebody-results-in-invalid-json
            stackoverflow.com/questions/2275359/jquery-single-quote-in-json-response
--%>
<c:set var="someJsonData" >
    <spring:escapeBody javaScriptEscape="true"> 
               if you don't have "user" an account
    </spring:escapeBody>
</c:set>    
{
    "status": "success",
    "body" : "${fn:replace(someJsonData, "\\\'","'")}" , <%-- [1] --%>
}

Here is the JSTL fn documentation

Probably not the cleanest/best solution to be honest. But it does the job until you find better.

Upvotes: 3

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280179

The Javascript Object Notation specification states that

Any character may be escaped.

As such,

{
    "status": "success",
    "body" : "if you don\'t have \"user\" an account"
}

is valid JSON.

If you need to create really custom text, you'll need to generate it yourself in a controller handler method or other component.

Ideally, you would use a @ResponseBody annotated method with a POJO that represents your status/body JSON object.

Upvotes: 3

Related Questions