用Java转义JSON字符串

Escape JSON String in Java

1.概述

在这个简短的教程中,我们将展示一些在Java中转义JSON字符串的方法。

我们将快速浏览最流行的JSON处理库,以及它们如何使转义实现简单任务。

2.哪里会出错?

让我们考虑将用户指定的消息发送到Web服务的简单但常见的用例。天真的,我们可以尝试:

1
2
String payload ="{"message":"" + message +""}";
sendMessage(payload);

但是,实际上,这会带来很多问题。

最简单的是消息是否包含引号:

1
{"message" :"My"message" breaks json" }

更糟糕的是,用户可能会故意破坏请求的语义。如果他发送:

1
Hello","role" :"admin

然后,该消息变为:

1
{"message" :"Hello","role" :"admin" }

最简单的方法是用适当的转义序列替换引号:

1
String payload ="{"message":"" + message.replace(""","\"") +""}";

但是,这种方法非常脆弱:

  • 需要为每个串联的值完成此操作,并且我们需要始终牢记我们已经转义了哪些字符串

  • 此外,由于消息结构随时间而变化,这可能会成为维护工作的头疼问题

  • 而且它很难阅读,更容易出错

  • 简而言之,我们需要采用更通用的方法。不幸的是,本地JSON处理功能仍处于JEP阶段,因此我们必须将目光转向各种开源JSON库。

    幸运的是,有几个JSON处理库。让我们快速浏览一下三个最受欢迎的。

    3. JSON-java库

    在我们的评测中,最简单,最小的库是JSON-java,也称为org.json。

    要构造一个JSON对象,我们只需创建一个JSONObject实例,并将其基本视为Map:

    1
    2
    3
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("message","Hello"World"");
    String payload = jsonObject.toString();

    这将引用"世界"周围的引号并将其转义:

    1
    2
    3
    {
      "message" :"Hello"World""
    }

    4.杰克逊图书馆

    Jackson是用于JSON处理的最受欢迎,用途最广泛的Java库之一。

    乍一看,Jackson的行为类似于toorg.json:

    1
    2
    3
    Map<String, Object> params = new HashMap<>();
    params.put("message","Hello"World"");
    String payload = new ObjectMapper().writeValueAsString(params);

    但是,Jackson还可以支持序列化Java对象。

    因此,通过将消息包装在自定义类中,让我们的示例有所增强:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Payload {
        Payload(String message) {
            this.message = message;
        }

        String message;
       
        // getters and setters
    }

    然后,我们需要一个ObjectMapper实例,我们可以将对象的实例传递给该实例:

    1
    String payload = new ObjectMapper().writeValueAsString(new Payload("Hello"World""));

    在这两种情况下,我们都得到与以前相同的结果:

    1
    2
    3
    {
      "message" :"Hello"World""
    }

    如果我们拥有一个已经转义的属性,并且需要对其进行序列化而没有任何进一步的转义,则我们可能想在该字段上使用Jackson的@JsonRawValue注释。

    5.番石榴图书馆

    Gsonis是Google的一个图书馆,经常与Jackson并驾齐驱。

    当然,我们可以像使用org.json一样进行操作:

    1
    2
    3
    JsonObject json = new JsonObject();
    json.addProperty("message","Hello"World"");
    String payload = new Gson().toJson(gsonObject);

    或者我们可以使用自定义对象,例如使用Jackson:

    1
    String payload = new Gson().toJson(new Payload("Hello"World""));

    我们将再次获得相同的结果。

    六,结论

    在这篇简短的文章中,我们已经看到了如何使用不同的开源库在Java中转义JSON字符串。

    与本文相关的所有代码都可以在Github上找到。