使用Gson遇到的特殊字符被轉碼問題

今天是用gson工具的時候,發現字符串中的‘=’被替換成了unicode編程格式的‘\u003d’,查看了下gson源碼,發現了gson在toString的時候的有以下操做:html

private void string(String value) throws IOException {
    String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
    out.write("\"");
    int last = 0;
    int length = value.length();
    for (int i = 0; i < length; i++) {
      char c = value.charAt(i);
      String replacement;
      if (c < 128) {
        replacement = replacements[c];
        if (replacement == null) {
          continue;
        }
      } else if (c == '\u2028') {
        replacement = "\\u2028";
      } else if (c == '\u2029') {
        replacement = "\\u2029";
      } else {
        continue;
      }
      if (last < i) {
        out.write(value, last, i - last);
      }
      out.write(replacement);
      last = i + 1;
    }
    if (last < length) {
      out.write(value, last, length - last);
    }
    out.write("\"");
  }

其中 HTML_SAFE_REPLACEMENT_CHARS 、REPLACEMENT_CHARS 分別爲:編程

REPLACEMENT_CHARS['"'] = "\\\"";
    REPLACEMENT_CHARS['\\'] = "\\\\";
    REPLACEMENT_CHARS['\t'] = "\\t";
    REPLACEMENT_CHARS['\b'] = "\\b";
    REPLACEMENT_CHARS['\n'] = "\\n";
    REPLACEMENT_CHARS['\r'] = "\\r";
    REPLACEMENT_CHARS['\f'] = "\\f";
    HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
    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";

可見HTML_SAFE_REPLACEMENT_CHARS包含了REPLACEMENT_CHARS。而是使用REPLACEMENT_CHARS仍是HTML_SAFE_REPLACEMENT_CHARS的關鍵在於boolean htmlSafe 的取值。該值是在建立Gson對象的時候傳入的。api

public Gson() {
    this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
        Collections.<Type, InstanceCreator<?>>emptyMap(), false, false, DEFAULT_JSON_NON_EXECUTABLE,
        true, false, false, LongSerializationPolicy.DEFAULT,
        Collections.<TypeAdapterFactory>emptyList());
  }

  Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
      final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
      boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
      boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
      LongSerializationPolicy longSerializationPolicy,
      List<TypeAdapterFactory> typeAdapterFactories) {
    this.constructorConstructor = new ConstructorConstructor(instanceCreators);
    this.serializeNulls = serializeNulls;
    this.generateNonExecutableJson = generateNonExecutableGson;
    this.htmlSafe = htmlSafe;
    this.prettyPrinting = prettyPrinting;

無參的構造函數,會將htmlSafe設置成true,也就是咱們經過 Gson gson = new Gson(); 生成的gson對象toString的時候會進行HTML_SAFE_REPLACEMENT_CHARS的字符替換。數組

帶有參數的構造函數,htmlSafe字段只有傳入的參數決定。而帶有參數的Gson構造函數只由GsonBuilder.create()方法調用。函數

public Gson create() {
    List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
    factories.addAll(this.factories);
    Collections.reverse(factories);
    factories.addAll(this.hierarchyFactories);
    addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);

    return new Gson(excluder, fieldNamingPolicy, instanceCreators,
        serializeNulls, complexMapKeySerialization,
        generateNonExecutableJson, escapeHtmlChars, prettyPrinting,
        serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
  }

可見GsonBuilder對象的escapeHtmlChars屬性控制着htmlSafe。而GsonBuilder的escapeHtmlChars的默認值爲true。但能夠經過GsonBuilder對象的disableHtmlEscaping方法來將escapeHtmlChars置爲false,然後在調用create方法生成Gson對象,這樣生成的Gson對象在toString的時候就只會替換REPLACEMENT_CHARS數組。工具

public GsonBuilder disableHtmlEscaping() {
    this.escapeHtmlChars = false;
    return this;
  }

總結:ui

生成的Gson對象的方法:this

①Gson gson = new Gson();.net

gson.toString(obj);

會對HTML_SAFE_REPLACEMENT_CHARS數組中的字符串進行替換

②GsonBuilder gsonBuilder = new GsonBuilder();3d

Gson gson = builder.create();

gson.toString(obj);

會對HTML_SAFE_REPLACEMENT_CHARS數組中的字符串進行替換

③ GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.disableHtmlEscaping();

 Gson gson = builder.create();   

 gson.toString(obj);

會對REPLACEMENT_CHARS數組中的字符串進行替換
相關文章
相關標籤/搜索