JavaScript无法从Java解析用Gson序列化的字符串[重复]

Posted

技术标签:

【中文标题】JavaScript无法从Java解析用Gson序列化的字符串[重复]【英文标题】:JavaScript unable to parse string serialized with Gson from Java [duplicate] 【发布时间】:2017-07-18 15:19:14 【问题描述】:

这不是this question 的重复,因为这里的问题是关于在 javascript 中以文字形式从 Java 序列化的 JSON 字符串的表示(而且它不仅仅是双引号,人们不得不担心)。

我正在使用Gson 在Java 中创建一个序列化的JSON 对象,随后我无法使用JSON.parse 从Javascript 内部化该对象。当我在我的 Java 对象中转义双引号时会发生这种情况。我发现令人困惑的是,Gson 应该负责正确的转义,并且 JSON 序列化格式与语言无关,所以当我从 Java 序列化时,我应该能够从 JavaScript 反序列化而不会感到头疼。

下面的最小代码:

Java 序列化

import java.util.*;
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

class LOV 
    List<String> values;

    public LOV(List<String> values) 
        this.values = values;
    


public class FooMain 

    private static final Gson gson = new GsonBuilder().serializeNulls().create();

    @SuppressWarnings("unchecked")
    public static <T> T fromJson(String json, Class<T> classOfT) 
        T target = (T) gson.fromJson(json, (Type) classOfT);
        return target;
    

    public static void main(String args[]) 
        List<String> values = new ArrayList<>();
        values.add("\"foo\"");
        LOV lov = new LOV(values);
        String s = gson.toJson(lov);
        System.out.printf("Stringified JSON is: [%s]\n", s);
        LOV lov2 = fromJson(s, LOV.class);
    

...上面的代码表明序列化和反序列化是可能的并且有效。我还为 LOV 类编写了一个 equals 方法来确定重新内部化的对象 (lov2) 等于最初序列化的对象(确实如此,我只是跳过这段代码以保持简短)。

上面的代码打印在控制台上:

Stringified JSON is: ["values":["\"foo\""]]

JavaScript 内化

然而,当我试图在 JavaScript 中内化由 Java 创建的字符串时:

JSON.parse('"values":["\"foo\""]');

……我明白了:

Uncaught SyntaxError: Unexpected token f in JSON at position 13(…)

分辨率

最后,根据接受的答案和对它的评论,我在 Java 端自动转义了一些字符,但有很多情况需要考虑。所以我必须(在 Java 中)执行以下所有操作:

s.replace("\\", "\\\\")
s.replace("\"", "\\\"")
s.replace("'", "\\'")

...在 JavaScript 方面我也必须这样做:

JSON.parse('the string literal prepared by Java'.replace(/\t/g, "\\t"));

这是有效的,但变得越来越复杂,我不确定我是否涵盖了所有案例,所以最后我只使用了StringEscapeUtils.escapeEcmaScript,它就像一个魅力。在 JavaScript 端使用 escapeEcmaScript 一个简单的 JSON.parse('the string literal prepared by Java') 就足够了。

【问题讨论】:

我认为这是因为您确实引用了该值但没有转义“\”。 JSON.parse('["values":["\\"foo\\""]]');WFM JSON.parse('["values":["\\\"foo\\\""]]'); 您还需要转义反斜杠,这样就可以转义双引号。另一种选择是可能对双引号进行编码,但是是的。 【参考方案1】:

您需要对 Javascript 的 JSON.parse 使用双反斜杠。这应该有效:

JSON.parse('"values":["\\"foo\\""]');

这是因为您还需要转义反斜杠。

【讨论】:

在这个有限的示例中手动更改字符串文字确实有效,但我需要 Javascript 中的函数或正则表达式来在需要时执行替换。我已经尝试过.replace(/\\/g, "\\\\"); 和其他各种形式,但似乎没有任何东西可以生成 JSON 可以在 JavaScript 中解析的字符串。 ***.com/questions/16144090/… 我显然已经看到了,它不起作用。这个问题是给 Javascript ('"values":["\"foo\""]') 的字符串实际上不包含任何要替换的反斜杠。出现的反斜杠是转义字符。替换字符串中的所有双引号更有意义,但这也会更改属性名称的字符串化形式,从而导致失败。 哦,我明白了。而且Java端不能加多余的转义字符? 这是接下来要尝试的事情,但由于我使用 GSON 库对对象进行 JSON 字符串化,我希望所有必要的转义都由库以某种方式处理。显然,在不同语言之间共享 JSON 字符串会遇到麻烦。

以上是关于JavaScript无法从Java解析用Gson序列化的字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Gson 解析验证我的 Junit 测试

JSON解析框架汇总

Java基础知识强化103:JSON解析框架汇总

Gson 无法解析 Kotlin 中的字符串 json 格式数据

求教json的有关问题,google库gson的bug有关问题

用GSON解析Json格式数据