【问题标题】:How do I unescape a JSON String using Java/Jackson?如何使用 Java/Jackson 取消转义 JSON 字符串?
【发布时间】:2016-04-14 21:28:58
【问题描述】:

我正在使用 Jackson 2.4.3 版将我的复杂 Java 对象转换为 String 对象,所以下面是我得到的输出。输出如下(仅供参考 - 我刚刚打印了部分输出)

"{\"FirstName\":\"John \",\"LastName\":cena,\"salary\":7500,\"skills\":[\"java\",\"python\"]}";

这是我的代码(PaymentTnx 是一个复杂的 Java 对象)

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
String lpTransactionJSON = mapper.writeValueAsString(paymentTxn);

我不想在我的 JSON 字符串中看到 \ 斜杠。我需要做什么才能获得如下字符串:

"{"FirstName":"John ","LastName":cena,"salary":7500,"skills":["java","python"]}";

【问题讨论】:

  • 等等。你什么时候看到斜线?

标签: java jackson


【解决方案1】:
String test = "{\"FirstName\":\"John \",\"LastName\":cena,\"salary\":7500,\"skills\":[\"java\",\"python\"]}";
        System.out.println(StringEscapeUtils.unescapeJava(test));

这可能会对你有所帮助。

【讨论】:

  • 这实际上已被弃用。有替代方案吗?
  • Apache 已将此类和函数移至不同的包中。 org.apache.commons.text.StringEscapeUtils.unescapeJson
  • 它现在包含在 commons-text-x.jar 中,而不是在 commons-lang-x.jar 中。
【解决方案2】:

我没有尝试过杰克逊。我只是有类似的情况。

我使用了 org.apache.commons.text.StringEscapeUtils.unescapeJson,但它不适用于格式错误的 JSON 格式,例如 {\"name\": \"john\"}

所以,我使用了这个类。完美运行。

https://gist.githubusercontent.com/jjfiv/2ac5c081e088779f49aa/raw/8bda15d27c73047621a94359492a5a9433f497b2/JSONUtil.java

// BSD License (http://lemurproject.org/galago-license)
package org.lemurproject.galago.utility.json;

public class JSONUtil {
  public static String escape(String input) {
    StringBuilder output = new StringBuilder();

    for(int i=0; i<input.length(); i++) {
      char ch = input.charAt(i);
      int chx = (int) ch;

      // let's not put any nulls in our strings
      assert(chx != 0);

      if(ch == '\n') {
        output.append("\\n");
      } else if(ch == '\t') {
        output.append("\\t");
      } else if(ch == '\r') {
        output.append("\\r");
      } else if(ch == '\\') {
        output.append("\\\\");
      } else if(ch == '"') {
        output.append("\\\"");
      } else if(ch == '\b') {
        output.append("\\b");
      } else if(ch == '\f') {
        output.append("\\f");
      } else if(chx >= 0x10000) {
        assert false : "Java stores as u16, so it should never give us a character that's bigger than 2 bytes. It literally can't.";
      } else if(chx > 127) {
        output.append(String.format("\\u%04x", chx));
      } else {
        output.append(ch);
      }
    }

    return output.toString();
  }

  public static String unescape(String input) {
    StringBuilder builder = new StringBuilder();

    int i = 0;
    while (i < input.length()) {
      char delimiter = input.charAt(i); i++; // consume letter or backslash

      if(delimiter == '\\' && i < input.length()) {

        // consume first after backslash
        char ch = input.charAt(i); i++;

        if(ch == '\\' || ch == '/' || ch == '"' || ch == '\'') {
          builder.append(ch);
        }
        else if(ch == 'n') builder.append('\n');
        else if(ch == 'r') builder.append('\r');
        else if(ch == 't') builder.append('\t');
        else if(ch == 'b') builder.append('\b');
        else if(ch == 'f') builder.append('\f');
        else if(ch == 'u') {

          StringBuilder hex = new StringBuilder();

          // expect 4 digits
          if (i+4 > input.length()) {
            throw new RuntimeException("Not enough unicode digits! ");
          }
          for (char x : input.substring(i, i + 4).toCharArray()) {
            if(!Character.isLetterOrDigit(x)) {
              throw new RuntimeException("Bad character in unicode escape.");
            }
            hex.append(Character.toLowerCase(x));
          }
          i+=4; // consume those four digits.

          int code = Integer.parseInt(hex.toString(), 16);
          builder.append((char) code);
        } else {
          throw new RuntimeException("Illegal escape sequence: \\"+ch);
        }
      } else { // it's not a backslash, or it's the last character.
        builder.append(delimiter);
      }
    }

    return builder.toString();
  }
}

【讨论】:

    【解决方案3】:

    Jackson 做:

    toString(paymentTxn);
    

    public String toString(Object obj) {
        try (StringWriter w = new StringWriter();) {
            new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writeValue(w, obj);
            return w.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    

    【讨论】:

      【解决方案4】:

      这里的 JSON 无效:

      "{"FirstName":"John ","LastName":cena,"salary":7500,"skills":["java","python"]}";
      

      这里是有效的 JSON,特别是单个字符串值:

      "{\"FirstName\":\"John \",\"LastName\":cena,\"salary\":7500,\"skills\":[\"java\",\"python\"]}";
      

      鉴于您正在调用writeValueAsString,这是正确的行为。我会建议writeValue,也许?

      【讨论】:

      • 当我们通常使用 writeValueAsString(Object) 时,它应该给出类似 "{"FirstName":"John","LastName":cena","salary":7500","skills" 的值:["java","python"]}";
      • 结果周围的双引号是结果的一部分吗?使用反引号 (`) 在视觉上将其分开。
      • 再一次,你试过用write 代替writeValueAsString吗?
      • 是的,我试过了但还是一样,writeValue有两个方法writeValue(OutputStram out, Object object)和writeValue(Writter w, Object value)
      猜你喜欢
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 2017-07-06
      • 2013-01-23
      • 2013-09-24
      • 1970-01-01
      • 2011-02-01
      相关资源
      最近更新 更多