2013-02-23 21 views
9

Ho appena iniziato a utilizzare Jackson a causa dell'integrazione con Spring Framework e ho riscontrato un problema con virgolette singole in un valore. Quando provo ad analizzare il JSON con jQuery nella pagina, ottengo un errore JavaScript "SyntaxError: missing) after argument list". Sono abituato a usare Gson per serializzare i miei oggetti e non ho incontrato questo problema poiché Gson sostituirà la citazione singola con Unicode \ u0027.serializzazione Jackson non gestisce correttamente virgolette singole

Ad esempio;
Java

public final class Person { 
    private String firstName; 
    private String lastName; 

    public Person() {} 

    public void setFirstName(String firstName) { 
    this.firstName = firstName; 
    } 

    public String getFirstName() { 
    return firstName; 
    } 

    public void setLastName(String lastName) { 
    this.lastName = lastName; 
    } 

    public String getLastName() { 
    return lastName; 
    } 
} 


JSON
In Jackson [{"person":{"firstName":"James","lastName":"O'tool"}}]
In GSON [{"person":{"firstName":"James","lastName":"O\u0027tool"}}]

JavaScript;
// This is where the JavaScript fails with the Jackson serialized object
$.parseJSON('${requestScope.person}');

Ho cercato una soluzione, ma non riesco a trovarne una. Qualcuno sa se è possibile configurare Jackson per gestire le virgolette singole nello stesso modo in cui lo fa Gson?

Grazie per il vostro tempo.

+2

Non provare ad emettere JSON in string letterali (sfuggirli ovviamente) e analizzarli. Basta emettere oggetti letterali! – Bergi

+0

Spiacente, ho dimenticato di includere che questa non è una chiamata Ajax e l'analisi dell'oggetto JSON si verifica su un JSP. Se si trattasse di una semplice chiamata ajax, non ci sarebbe alcun problema. – Jason

+0

No, stai provando ad analizzare una stringa JSON (erroneamente con caratteri di escape) con JavaScript (non JSP) – Bergi

risposta

5

L'altra risposta mostra un modo per farlo e dovrebbe funzionare piuttosto bene.

Ma c'è un altro modo per fare questo pure, che è po 'meno lavoro, ha spiegato a "Forcing escaping of HTML characters in JSON using Jackson"

+0

Questo è quello che stavo cercando. Grazie! Spero solo che ci fosse un modo per registrare gli CharacterEscapes personalizzati in primavera con la classe Jackson2ObjectMapperFactoryBean. – Jason

+0

Potrebbe essere utile suggerire questo al team di sviluppo di Spring? – StaxMan

2

Per risolvere questo problema, ho finito per creare un serializzatore String personalizzato per Jackson. Ho preso in prestito qualche fonte da Gson.

public class HtmlStringSerializer extends StdSerializer<String> { 
     protected HtmlStringSerializer() { super(String.class); } 

     private static final String[] HTML_SAFE_REPLACEMENT_CHARS; 
     static { 
     HTML_SAFE_REPLACEMENT_CHARS = new String[128]; 
     for (int i = 0; i <= 0x1f; i++) { 
      HTML_SAFE_REPLACEMENT_CHARS[i] = String.format("\\u%04x", i); 
     } 
     HTML_SAFE_REPLACEMENT_CHARS['"'] = "\\\""; 
     HTML_SAFE_REPLACEMENT_CHARS['\\'] = "\\\\"; 
     HTML_SAFE_REPLACEMENT_CHARS['\t'] = "\\t"; 
     HTML_SAFE_REPLACEMENT_CHARS['\b'] = "\\b"; 
     HTML_SAFE_REPLACEMENT_CHARS['\n'] = "\\n"; 
     HTML_SAFE_REPLACEMENT_CHARS['\r'] = "\\r"; 
     HTML_SAFE_REPLACEMENT_CHARS['\f'] = "\\f"; 
     HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c"; 
     HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e"; 
     HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026"; 
     HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d"; 
     HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027"; 
     } 

     @Override 
     public void serialize(String string, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException { 
     int last = 0; 
     int length = string.length(); 
     StringBuilder sb = new StringBuilder(length); 

     for (int i = 0; i < length; i++) { 
      char c = string.charAt(i); 
      String replacement; 
      if (c < 128) { 
      replacement = HTML_SAFE_REPLACEMENT_CHARS[c]; 
      if (replacement == null) { continue; } 
      } else if (c == '\u2028') { 
      replacement = "\\u2028"; 
      } else if (c == '\u2029') { 
      replacement = "\\u2029"; 
      } else { 
      continue; 
      } 
      if (last < i) { 
     sb.append(string.substring(last, i)); 
      } 
      sb.append(replacement); 
      last = i + 1; 
     } 
     if (last < length) { 
      sb.append(string.substring(last)); 
     } 
     gen.writeString(sb.toString()); 
     } 
    } 
0

@Bergi stava cercando di dire: non utilizzare:

$.parseJSON('${requestScope.person}') 

semplicemente utilizzare

${requestScope.person} 

direttamente!

+0

È divertente: hai interpretato il commento dal lato client e l'ho interpretato dal lato server. Pensavo che @Bergi stesse dicendo di passare oggetti in Jackson in modo che non sfuggisse ai caratteri di citazione in una stringa. – ingyhere

Problemi correlati