2013-02-23 3 views
9

스프링 프레임 워크와의 통합으로 인해 Jackson을 사용하기 시작했으며 값에 작은 따옴표가있는 문제가 발생했습니다. JSON을 페이지에서 jQuery와 구문 분석하려고하면 JavaScript 오류 "SyntaxError: missing) after argument list"가 발생합니다. 저는 Gson을 사용하여 객체를 직렬화하는 데 익숙합니다. Gson이 작은 따옴표를 Unicode \ u0027로 바꾸므로이 문제가 발생하지 않습니다.Jackson 직렬화가 작은 따옴표를 제대로 처리하지 않음

예 :
자바

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"}}]

자바 스크립트에서 [{"person":{"firstName":"James","lastName":"O'tool"}}]
;
// This is where the JavaScript fails with the Jackson serialized object
$.parseJSON('${requestScope.person}');

해결책을 찾았지만 찾을 수 없습니다. Gson이하는 것과 같은 방법으로 작은 따옴표를 처리하도록 Jackson을 구성 할 수 있습니까?

감사합니다.

+2

JSON을 문자열 리터럴로 출력하지 말고 (물론 이스케이프 처리하지 마세요) 구문 분석하십시오. 그냥 개체 리터럴을 출력! – Bergi

+0

죄송합니다, 이것은 ajax 호출이 아니며 JSON 객체의 구문 분석이 JSP에서 발생한다는 것을 잊었습니다. 이것이 곧바로 아약스 전화라면 문제가되지 않을 것입니다. – Jason

+0

아니요, JSP가 아닌 JavaScript로 (잘못 이스케이프 된) JSON 문자열을 구문 분석하려고합니다. – Bergi

답변

5

다른 대답은이를 수행하는 한 가지 방법을 보여줍니다.

그러나 조금 덜 작업을하다뿐만 아니라이 작업을 수행하는 또 다른 방법은, 거기는 "Forcing escaping of HTML characters in JSON using Jackson는"

+0

내가 찾고 있던 것이 그 것이다. 고맙습니다! 스프링에 사용자 정의 CharacterEscapes를 Jackson2ObjectMapperFactoryBean 클래스로 등록하는 방법이 있었으면 좋겠습니다. – Jason

+0

스프링 데브 팀에 제안할만한 가치가 있을까요? – StaxMan

2

이 문제를 해결하기 위해 Jackson 용 사용자 지정 String serializer를 작성했습니다. 나는 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가 시도되었다에서 설명 말 : 사용하지 않는 : 단순히

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

${requestScope.person} 

을 직접 사용하십시오!

+0

재미 있습니다. 클라이언트 측의 설명을 해석하고 서버 측에서 해석했습니다. @Bergi는 잭슨에 객체를 전달하여 String에서 따옴표 문자를 이스케이프 처리하지 않도록 말하고 있다고 생각했습니다. – ingyhere

관련 문제