2013-02-23 24 views
9

Spring Frameworkとの統合のためにJacksonを使い始めたばかりで、値の一重引用符で問題が発生しました。ページのjQueryでJSONを解析しようとすると、JavaScriptエラー"SyntaxError: missing) after argument list"が発生します。私はGsonを使用してオブジェクトをシリアライズしていましたが、Gsonが一重引用符をUnicode \ u0027に置き換えてしまうため、この問題は発生しません。ジャクソンのシリアル化で一重引用符が正しく処理されない

たとえば、
の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
Gson [{"person":{"firstName":"James","lastName":"O\u0027tool"}}]

はJavaScript [{"person":{"firstName":"James","lastName":"O'tool"}}]

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

私は解決策を探しましたが、見つけられませんでした。 Gsonが行うのと同じ方法でシングルクォートを処理するようにジャクソンを設定することができるかどうかは知っていますか?

ありがとうございます。

+2

JSONを文字列リテラル(もちろんエスケープ)に出力して解析しないでください。ただオブジェクトリテラルを出力してください! – Bergi

+0

申し訳ありませんが、これはajax呼び出しではなく、JSONオブジェクトの解析がJSPで行われることを含めるのを忘れていました。これがまっすぐなアヤックスコールだった場合、問題はありません。 – Jason

+0

いいえ、間違ってエスケープされたJSON文字列をJavaScript(JSPではなく)で解析しようとしています – Bergi

答えて

5

他の答えは、これを行うための一つの方法を示しており、それはかなりうまく動作するはずです。

しかし、少し少ない作業であるだけでなく、これを行うための別の方法があり、@Bergiが言おうとした「Forcing escaping of HTML characters in JSON using Jackson

+0

それは私が探していたものです。ありがとうございました! SpringのカスタムCharacterEscapesをJackson2ObjectMapperFactoryBeanクラスに登録する方法があったらいいですね。 – Jason

+0

Springデベロッパーチームにそれを示唆する価値がありますか? – StaxMan

2

この問題を解決するために、JacksonのカスタムStringシリアライザを作成しました。私は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

で説明:使用しないでください。

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

単に使用する

${requestScope.person} 

を直接使用してください!

+0

それは面白いです:あなたはクライアント側からのコメントを解釈し、私はそれをサーバー側から解釈しました。私は@BergiがオブジェクトをJacksonに渡して、文字列内の引用文字をエスケープしないと言っていたと思いました。 – ingyhere

関連する問題