2011-06-17 19 views
17

Estamos construyendo una API reparador utilizando Spring MVC y FreeMarker como el lenguaje de plantillas. Hemos elegido para construir respuestas JSON en el FreeMarkercómo escapar de las cadenas JSON en FreeMarker

Ejemplo freemarker.ftl:

{ 
"field1" : "${response.value1}", 
"field2" : "${response.value2}" 
} 

Tenemos un problema cuando las cadenas en los valores contienen comillas (o cualquiera de los otros personajes de la sintaxis JSON)

La pregunta: ¿Cómo puedo escapar de estas cadenas usando freemarker?

Hemos visto ?xml o ?html pero no cubren todos los personajes relevantes (tales como \).

EDIT:?js_string escapó de la cadena para cumplir con JavaScript. Y dado que JSON está basado en JavaScript (JavaScript Object Notation), funcionará.

EDIT2: En caso de que aparezca una comilla simple, ?js_script se escapará, lo que nuevamente conduce a JSON no válido. La revisión para es:

${variable?js_string?replace("\\'", "\'")} 

y si realmente quiere ser exigente:

${variable?js_string?replace("\\'", "\'")?replace("\\>",">")} 

Alternativamente, si se utiliza la primavera: 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

+0

+1 para la alternativa de primavera –

Respuesta

23

Usted está buscando el operador ?js_string.

{ 
"field1" : "${response.value1?js_string}", 
"field2" : "${response.value2?js_string}" 
} 

Eso se ocupará de escapar de las comillas, las barras diagonales inversas, et. todo para hacer feliz a tu JS.

Editar: Acabo de ver que introdujeron un operador ?json_string en Freemarker 2.3.19. Consulte here para ver exactamente cómo funciona. Y había gran regocijo ...

+0

¿Cuál es la ventaja de js_string sobre j_string en este caso??? – Skurpi

+0

@Skurpi La ventaja es que 'js_string' hace el escape necesario, mientras que' j_string' no. – Waldheinz

+0

@Waldheinz & @stevevls ¡Gracias! – Skurpi

2

Utilice un FreeMarker macro de combinar todas las respuestas anteriores, al tiempo que la plantilla sea más legible y fácil de mantener:

<#macro json_string string>${string?js_string?replace("\\'", "\'")?replace("\\>", ">")}</#macro> 
{ 
"field1" : "<@json_string "${response.value1}"/>", 
"field2" : "<@json_string "${response.value2}"/>" 
} 

Si desea volver a utilizar la macro en varias plantillas, ponerlo en su propio archivo y include the file en vez de duplicar la macro:

<#include "/path/to/macro.ftl"> 
+0

Esto es en realidad lo que hicimos, pero pusimos alguna funcionalidad adicional en la que tuvimos que usar: <#macro hazStringContenido content> \t <#if content? Has_content && content! = ""> "$ {Content? Js_string ? replace ("\\" "," \ '")? replace (" \\> ","> ")}" <#else> nulo Skurpi

Cuestiones relacionadas