【问题标题】:JSONObject contains escape charactersJSONObject 包含转义字符
【发布时间】:2013-10-26 16:44:06
【问题描述】:

我正在构建一个模拟器来将 JSON 数据发布到我正在运行的服务中。

JSON 应该如下所示:

{"sensor":
       {"id":"SENSOR1","name":"SENSOR","type":"Temperature","value":100.12,"lastDateValue":"\/Date(1382459367723)\/"}
}

我在 Chrome 中使用“高级 REST 客户端”进行了尝试,效果很好。 ServiceStack 网络服务正确解析了日期。

所以,重点是编写一个传感器模拟器,将这样的数据发布到 Web 服务。

我用 Java 创建了这个,所以我可以在我的树莓派上运行它。

这是代码:

    public static void main(String[] args) {

    String url = "http://localhost:63003/api/sensors";
    String sensorname = "Simulated sensor";
    int currentTemp = 10;
    String dateString = "\\" + "/Date(" + System.currentTimeMillis() + ")\\" + "/";
    System.out.println(dateString);

    System.out.println("I'm going to post some data to: " + url);

    //Creating the JSON Object
    JSONObject data = new JSONObject();
    data.put("id", sensorname);
    data.put("name", sensorname);
    data.put("type", "Temperature");
    data.put("value", currentTemp);
    data.put("lastDateValue", dateString);
    JSONObject sensor = new JSONObject().put("sensor",  data);

    //Print out the data to be sent
    StringWriter out = new StringWriter();
    sensor.write(out);

    String jsonText = out.toString();
    System.out.print(jsonText);

    //Sending the object
    HttpClient c = new DefaultHttpClient();
    HttpPost p = new HttpPost(url);
    p.setEntity(new StringEntity(sensor.toString(), ContentType.create("application/json")));

    try {
        HttpResponse r = c.execute(p);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

这个程序的输出如下:

\/Date(1382459367723)\/
I'm going to post some data to: http://localhost:63003/api/sensors
{"sensor":{"lastDateValue":"\\/Date(1382459367723)\\/","id":"Simulated sensor","name":"Simulated sensor","value":10,"type":"Temperature"}}

这里的问题是 JSONObject 字符串仍然包含这些转义字符。但是当我在开头打印字符串时,它不包含转义字符。有没有办法摆脱这些?我的服务无法解析这些..

这是我在 chrome 中与其余客户端一起发送的示例:

 {"sensor":{"id":"I too, am a sensor!","name":"Willy","type":"Temperature","value":100.12,"lastDateValue":"\/Date(1382459367723)\/"}}

【问题讨论】:

  • 如果您的服务无法解析转义字符,那么这不是服务中的错误吗?修复解析器而不是尝试生成不正确的 JSON。
  • 恐怕不是我的服务实现。我正在使用 ServiceStack WCF 服务。所以我真的无法解决这个问题。我的意思是,如果字符串以正确的方式表示,JSONObject 怎么会把它们放在那里?
  • 在构造日期字符串时尝试对这些转义字符使用 unicode,并查看服务是否能够解释结果。 unicode 是 \ ==> \u005c 和 / ==> \u002f

标签: java jsonobject


【解决方案1】:

JSONObject 正确编码了字符串。 This page 描述了如何在 JavaScript(以及扩展的 JSON)中对字符串文字进行转义。以下注释对于理解您的示例中发生的情况很重要:

对于表 2.1 中未列出的字符,前面的反斜杠将被忽略,但这种用法已被弃用,应避免使用。

您的示例 ("\/Date(1382459367723)\/") 在 / 之前使用了反斜杠。因为/ 不在表2.1 中,所以\ 应该被忽略。如果您的服务没有忽略 \,那么它要么有错误,要么不是 JSON 解析器(可能它使用类似于但不完全是 JSON 的数据格式)。

由于您需要生成不符合标准的 JSON,因此您将无法使用标准工具来执行此操作。您的两个选择是编写自己的非 JSON 编码器,或者避免必须转义的字符,例如 \"

【讨论】:

  • 请注意,最新版本的 JSON 规范 RFC 8259 现在允许反斜杠出现在字符串文字中的斜杠之前。
【解决方案2】:

@pburka 是正确的。如果您想以\/Date(1382459367723)\/ 格式发送,请尝试将黑斜线转义两次,如下所示

String dateString = "\\\\" + "/Date(" + System.currentTimeMillis() + ")\\\\" + "/";

在第一遍中,dateString 将使其成为\\/Date(1382459367723)\\/,最后 JSONObject 将在其缓冲区内部添加额外的反斜杠,即\\\/Date(1382459367723)\\\/,以便根据 JSON 解析规则忽略 / 之前的黑斜杠,您将获得期望的结果,即\/Date(1382459367723)\/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2019-05-08
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    相关资源
    最近更新 更多