GVKun编程网logo

带有引号的JSON.parse字符串(带引号的json字符串传前台)

18

在本文中,我们将给您介绍关于带有引号的JSON.parse字符串的详细内容,并且为您解答带引号的json字符串传前台的相关问题,此外,我们还将为您提供关于4.JSON字符串是如何被解析的?JsonPa

在本文中,我们将给您介绍关于带有引号的JSON.parse字符串的详细内容,并且为您解答带引号的json字符串传前台的相关问题,此外,我们还将为您提供关于4. JSON字符串是如何被解析的?JsonParser了解一下、bash – 包含带有引号的多个args的变量、Gson的JSON字符串:删除双引号、Java - 手动解析不带引号的JSON字符串的知识。

本文目录一览:

带有引号的JSON.parse字符串(带引号的json字符串传前台)

带有引号的JSON.parse字符串(带引号的json字符串传前台)

我有这个:

JSON.parse(''{"130.00000001":{"p_cod":"130.00000001","value":"130.00000001 HDD Upgrade to 2x 250GB HDD 2.5\" SATA2 7200rpm"}}'');

JSONLint表示这是完全有效的json。但是执行时出现JSON.parse错误。

但是,如果我将代码更改为:

    JSON.parse(''{"130.00000001":{"p_cod":"130.00000001","value":"130.00000001 HDD Upgrade to 2x 250GB HDD 2.5\\" SATA2 7200rpm"}}'');

(请注意双反斜杠)

它可以工作,但是现在JSONLint表示invalid json

有人可以帮助您了解这种行为吗?

答案1

小编典典

有线格式和您必须在代码中编写的格式之间是有区别的。当您在代码中声明此代码时,您需要在文字中使用双-\,以便字符串获得一个反斜杠(否则,它将\\解释为一个转义序列,仅声明一个“并将其放入您的字符串中)。如果打印出文字的值,则会看到一个反斜杠。

4. JSON字符串是如何被解析的?JsonParser了解一下

4. JSON字符串是如何被解析的?JsonParser了解一下

公司不是你家,领导不是你妈。本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈、MyBatis、JVM、中间件等小而美的专栏供以免费学习。关注公众号【BAT的乌托邦】逐个击破,深入掌握,拒绝浅尝辄止。

前言

各位好,我是A哥(YourBatman)。上篇文章:3. 懂了这些,方敢在简历上说会用Jackson写JSON 聊完,流式API的写部分可以认为你已完全掌握了,本文了解它读的部分。

版本约定

  • Jackson版本:2.11.0
  • Spring Framework版本:5.2.6.RELEASE
  • Spring Boot版本:2.3.0.RELEASE
小贴士:截止到本文,本系列前面所有示例都只仅仅导入jackson-core而已,后续若要新增jar包我会额外说明,否则相同

正文

什么叫读JSON?就是把一个JSON 字符串 解析为对象or树模型嘛,因此也称作解析JSON串。Jackson底层流式API使用JsonParser来完成JSON字符串的解析。

最简使用Demo

准备一个POJO:

@Data
public class Person {
    private String name;
    private Integer age;
}

测试用例:把一个JSON字符串绑定(封装)进一个POJO对象里

@Test
public void test1() throws IOException {
    String jsonStr = "{\"name\":\"YourBatman\",\"age\":18}";
    Person person = new Person();

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        
        // 只要还没结束"}",就一直读
        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("name".equals(fieldname)) {
                jsonParser.nextToken();
                person.setName(jsonParser.getText());
            } else if ("age".equals(fieldname)) {
                jsonParser.nextToken();
                person.setAge(jsonParser.getIntValue());
            }
        }
        
        System.out.println(person);
    }
}

运行程序,输出:

Person(name=YourBatman, age=18)

成功把一个JSON字符串的值解析到Person对象。你可能会疑问,怎么这么麻烦?那当然,这是底层流式API,纯手动档嘛。你获得了性能,可不要失去一些便捷性嘛。

小贴士:底层流式API一般面向“专业人士”,应用级开发使用高阶API ObjectMapper即可。当然,读完本系列就能让你完全具备“专业人士”的实力?

JsonParser针对不同的value类型,提供了非常多的方法用于实际值的获取。

直接值获取:

// 获取字符串类型
public abstract String getText() throws IOException;

// 数字Number类型值 标量值(支持的Number类型参照NumberType枚举)
public abstract Number getNumberValue() throws IOException;
public enum NumberType {
    INT, LONG, BIG_INTEGER, FLOAT, DOUBLE, BIG_DECIMAL
};

public abstract int getIntValue() throws IOException;
public abstract long getLongValue() throws IOException;
...
public abstract byte[] getBinaryValue(Base64Variant bv) throws IOException;

这类方法可能会抛出异常:比如value值本不是数字但你调用了getInValue()方法~

小贴士:如果value值是null,像getIntValue()、getBooleanValue()等这种直接获取方法是会抛出异常的,但getText()不会

带默认值的值获取,具有更好安全性:

public String getValueAsString() throws IOException {
    return getValueAsString(null);
}
public abstract String getValueAsString(String def) throws IOException;
...
public long getValueAsLong() throws IOException {
    return getValueAsLong(0);
}
public abstract long getValueAsLong(long def) throws IOException;
...

此类方法若碰到数据的转换失败时,不会抛出异常,把def作为默认值返回。

组合方法

JsonGenerator一样,JsonParser也提供了高钙片组合方法,让你更加便捷的使用。

自动绑定

听起来像高级功能,是的,它必须依赖于ObjectCodec去实现,因为实际是全部委托给了它去完成的,也就是我们最为熟悉的readXXX系列方法:

我们知道,ObjectMapper就是一个ObjectCodec,它属于高级API,本文显然不会用到ObjectMapper它喽,因此我们自己手敲一个实现来完成此功能。

自定义一个ObjectCodec,Person类专用:用于把JSON串自动绑定到实例属性。

public class PersonObjectCodec extends ObjectCodec {
    ...
    @SneakyThrows
    @Override
    public <T> T readValue(JsonParser jsonParser, Class<T> valueType) throws IOException {
        Person person = (Person) valueType.newInstance();

        // 只要还没结束"}",就一直读
        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("name".equals(fieldname)) {
                jsonParser.nextToken();
                person.setName(jsonParser.getText());
            } else if ("age".equals(fieldname)) {
                jsonParser.nextToken();
                person.setAge(jsonParser.getIntValue());
            }
        }

        return (T) person;
    }
    ...
}

有了它,就可以实现我们的自动绑定了,书写测试用例:

@Test
public void test3() throws IOException {
    String jsonStr = "{\"name\":\"YourBatman\",\"age\":18, \"pickName\":null}";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        jsonParser.setCodec(new PersonObjectCodec());

        System.out.println(jsonParser.readValueAs(Person.class));
    }
}

运行程序,输出:

Person(name=YourBatman, age=18)

这就是ObjectMapper自动绑定的核心原理所在,其它更为强大能力将在后续章节详细展开。

JsonToken

在上例解析过程中,有一个非常重要的角色,那便是:JsonToken。它表示解析JSON内容时,用于返回结果的基本标记类型的枚举。

public enum JsonToken {
    NOT_AVAILABLE(null, JsonTokenId.ID_NOT_AVAILABLE),
    
    START_OBJECT("{", JsonTokenId.ID_START_OBJECT),
    END_OBJECT("}", JsonTokenId.ID_END_OBJECT),
    START_ARRAY("[", JsonTokenId.ID_START_ARRAY),
    END_ARRAY("]", JsonTokenId.ID_END_ARRAY),

    // 属性名(key)
    FIELD_NAME(null, JsonTokenId.ID_FIELD_NAME),

    // 值(value)
    VALUE_EMBEDDED_OBJECT(null, JsonTokenId.ID_EMBEDDED_OBJECT),
    VALUE_STRING(null, JsonTokenId.ID_STRING),
    VALUE_NUMBER_INT(null, JsonTokenId.ID_NUMBER_INT),
    VALUE_NUMBER_FLOAT(null, JsonTokenId.ID_NUMBER_FLOAT),
    VALUE_TRUE("true", JsonTokenId.ID_TRUE),
    VALUE_FALSE("false", JsonTokenId.ID_FALSE),
    VALUE_NULL("null", JsonTokenId.ID_NULL),
}

为了辅助理解,A哥用一个例子,输出各个部分一目了然:

@Test
public void test2() throws IOException {
    String jsonStr = "{\"name\":\"YourBatman\",\"age\":18, \"pickName\":null}";
    System.out.println(jsonStr);
    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {

        while (true) {
            JsonToken token = jsonParser.nextToken();
            System.out.println(token + " -> 值为:" + jsonParser.getValueAsString());

            if (token == JsonToken.END_OBJECT) {
                break;
            }
        }
    }
}

运行程序,输出:

{"name":"YourBatman","age":18, "pickName":null}
START_OBJECT -> 值为:null


FIELD_NAME -> 值为:name
VALUE_STRING -> 值为:YourBatman

FIELD_NAME -> 值为:age
VALUE_NUMBER_INT -> 值为:18

FIELD_NAME -> 值为:pickName
VALUE_NULL -> 值为:null


END_OBJECT -> 值为:null

从左至右解析,一一对应。各个部分用下面这张图可以简略表示出来:

小贴士:解析时请确保你的的JSON串是合法的,否则抛出JsonParseException异常

JsonParser的Feature

它是JsonParser的一个内部枚举类,共15个枚举值:

public enum Feature {
    AUTO_CLOSE_SOURCE(true),
    
    ALLOW_COMMENTS(false),
    ALLOW_YAML_COMMENTS(false),
    ALLOW_UNQUOTED_FIELD_NAMES(false),
    ALLOW_SINGLE_QUOTES(false),
    @Deprecated
    ALLOW_UNQUOTED_CONTROL_CHARS(false),
    @Deprecated
    ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false),
    @Deprecated
    ALLOW_NUMERIC_LEADING_ZEROS(false),
    @Deprecated
    ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS(false),
    @Deprecated
    ALLOW_NON_NUMERIC_NUMBERS(false),
    @Deprecated
    ALLOW_MISSING_VALUES(false),
    @Deprecated
    ALLOW_TRAILING_COMMA(false),
    
    STRICT_DUPLICATE_DETECTION(false),
    IGNORE_UNDEFINED(false),
    INCLUDE_SOURCE_IN_LOCATION(true);
}
小贴士:枚举值均为bool类型,括号内为默认值

每个枚举值都控制着JsonParser不同的行为。下面分类进行解释

底层I/O流相关

自2.10版本后,使用StreamReadFeature#AUTO_CLOSE_SOURCE代替

Jackson的流式API指的是I/O流,所以即使是,底层也是用I/O流(Reader)去读取然后解析的。

AUTO_CLOSE_SOURCE(true)

原理和JsonGenerator的AUTO_CLOSE_TARGET(true)一样,不再解释,详见上篇文章对应部分。

支持非标准格式

JSON是有规范的,在它的规范里并没有描述到对注释的规定、对控制字符的处理等等,也就是说这些均属于非标准行为。比如这个JSON串:

{
    "name" : "YourBarman", // 名字
    "age" : 18 // 年龄
}

你看,若你这么写IDEA都会飘红提示你:

但是,在很多使用场景(特别是JavaScript)里,我们会在JSON串里写注释(属性多时尤甚)那么对于这种串,JsonParser如何控制处理呢?它提供了对非标准JSON格式的兼容,通过下面这些特征值来控制。

ALLOW_COMMENTS(false)
自2.10版本后,使用JsonReadFeature#ALLOW_JAVA_COMMENTS代替

是否允许/* */或者//这种类型的注释出现。

@Test
public void test4() throws IOException {
    String jsonStr = "{\n" +
            "\t\"name\" : \"YourBarman\", // 名字\n" +
            "\t\"age\" : 18 // 年龄\n" +
            "}";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        // 开启注释支持
        // jsonParser.enable(JsonParser.Feature.ALLOW_COMMENTS);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("name".equals(fieldname)) {
                jsonParser.nextToken();
                System.out.println(jsonParser.getText());
            } else if ("age".equals(fieldname)) {
                jsonParser.nextToken();
                System.out.println(jsonParser.getIntValue());
            }
        }
    }
}

运行程序,抛出异常:

com.fasterxml.jackson.core.JsonParseException: Unexpected character (''/'' (code 47)): maybe a (non-standard) comment? (not recognized as one since Feature ''ALLOW_COMMENTS'' not enabled for parser)
 at [Source: (String)"{
    "name" : "YourBarman", // 名字
    "age" : 18 // 年龄
}"; line: 2, column: 26]

放开注释的代码,再次运行程序,正常work

ALLOW_YAML_COMMENTS(false)
自2.10版本后,使用JsonReadFeature#ALLOW_YAML_COMMENTS代替

顾名思义,开启后将支持Yaml格式的的注释,也就是#形式的注释语法。

ALLOW_UNQUOTED_FIELD_NAMES(false)
自2.10版本后,使用JsonReadFeature#ALLOW_UNQUOTED_FIELD_NAMES代替

是否允许属性名不带双引号"",比较简单,示例略。

ALLOW_SINGLE_QUOTES(false)
自2.10版本后,使用JsonReadFeature#ALLOW_SINGLE_QUOTES代替

是否允许属性名支持单引号,也就是使用''''包裹,形如这样:

{
    ''age'' : 18
}
ALLOW_UNQUOTED_CONTROL_CHARS(false)
自2.10版本后,使用JsonReadFeature#ALLOW_UNESCAPED_CONTROL_CHARS代替

是否允许JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)。 由于JSON规范要求对所有控制字符使用引号,这是一个非标准的特性,因此默认禁用。

那么,哪些字符属于控制字符呢?做个简单科普:我们一般说的ASCII码共128个字符(7bit),共分为两大类

控制字符

控制字符,也叫不可打印字符。第0~32号及第127号(共34个)是控制字符,例如常见的:LF(换行)CR(回车)、FF(换页)、DEL(删除)、BS(退格)等都属于此类。

控制字符大部分已经废弃不用了,它们的用途主要是用来操控已经处理过的文字,ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。

话外音:你看不见我,但我对你影响还蛮大
非控制字符

也叫可显示字符,或者可打印字符,能从键盘直接输入的字符。比如0-9数字,逗号、分号这些等等。

话外音:你肉眼能看到的字符就属于非控制字符
ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false)
自2.10版本后,使用JsonReadFeature#ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER代替

是否允许*反斜杠*转义任何字符。这句话不是非常好理解,看下面这个例子:

@Test
public void test4() throws IOException {
    String jsonStr = "{\"name\" : \"YourB\\''atman\" }";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        // jsonParser.enable(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("name".equals(fieldname)) {
                jsonParser.nextToken();
                System.out.println(jsonParser.getText());
            }
        }
    }
}

运行程序,报错:

com.fasterxml.jackson.core.JsonParseException: Unrecognized character escape '''''' (code 39)
 at [Source: (String)"{"name" : "YourB\''atman" }"; line: 1, column: 19]
 ...

放开注释掉的代码,再次运行程序,一切正常,输出:YourB''atman

ALLOW_NUMERIC_LEADING_ZEROS(false)
自2.10版本后,使用JsonReadFeature#ALLOW_LEADING_ZEROS_FOR_NUMBERS代替

是否允许像00001这样的“数字”出现(而不报错)。看例子:

@Test
public void test5() throws IOException {
    String jsonStr = "{\"age\" : 00018 }";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        // jsonParser.enable(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("age".equals(fieldname)) {
                jsonParser.nextToken();
                System.out.println(jsonParser.getIntValue());
            }
        }
    }
}

运行程序,输出:

com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed
 at [Source: (String)"{"age" : 00018 }"; line: 1, column: 11]
 ...

放开注掉的代码,再次运行程序,一切正常。输出18

ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS(false)
自2.10版本后,使用JsonReadFeature#ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS代替

是否允许小数点.打头,也就是说.1这种小数格式是否合法。默认是不合法的,需要开启此特征才能支持,例子就略了,基本同上。

ALLOW_NON_NUMERIC_NUMBERS(false)
自2.10版本后,使用JsonReadFeature#ALLOW_NON_NUMERIC_NUMBERS代替

是否允许一些解析器识别一组“非数字”(如NaN)作为合法的浮点数值。这个属性和上篇文章的JsonGenerator#QUOTE_NON_NUMERIC_NUMBERS特征值是遥相呼应的。

@Test
public void test5() throws IOException {
    String jsonStr = "{\"percent\" : NaN }";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        // jsonParser.enable(JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("percent".equals(fieldname)) {
                jsonParser.nextToken();
                System.out.println(jsonParser.getFloatValue());
            }
        }
    }
}

运行程序,抛错:

com.fasterxml.jackson.core.JsonParseException: Non-standard token ''NaN'': enable JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS to allow
 at [Source: (String)"{"percent" : NaN }"; line: 1, column: 17]

放开注释掉的代码,再次运行,一切正常。输出:

NaN
小贴士:NaN也可以表示一个Float对象,是的你没听错,即使它不是数字但它也是Float类型。具体你可以看看Float源码里的那几个常量
ALLOW_MISSING_VALUES(false)
自2.10版本后,使用JsonReadFeature#ALLOW_MISSING_VALUES代替

是否允许支持JSON数组中“缺失”值。怎么理解:数组中缺失了值表示两个逗号之间,啥都没有,形如这样[value1, , value3]

@Test
public void test6() throws IOException {
    String jsonStr = "{\"names\" : [\"YourBatman\",,\"A哥\",,] }";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        // jsonParser.enable(JsonParser.Feature.ALLOW_MISSING_VALUES);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("names".equals(fieldname)) {
                jsonParser.nextToken();

                while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
                    System.out.println(jsonParser.getText());
                }
            }
        }
    }
}

运行程序,抛错:

YourBatman // 能输出一个,毕竟第一个part(JsonToken)是正常的嘛

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('','' (code 44)): expected a valid value (JSON String, Number, Array, Object or token ''null'', ''true'' or ''false'')
 at [Source: (String)"{"names" : ["YourBatman",,"A哥",,] }"; line: 1, column: 27]

放开注释掉的代码,再次运行,一切正常,结果为:

YourBatman
null
A哥
null
null

请注意:此时数组的长度是5哦。

小贴士:此处用的String类型展示结果,是因为null可以作为String类型(jsonParser.getText()得到null是合法的)。但如果你使用的int类型(或者bool类型),那么如果是null的话就报错喽Current token (VALUE_NULL) not of boolean type,有兴趣的亲可自行尝试,巩固下理解的效果。报错原因文上已有说明~
ALLOW_TRAILING_COMMA(false)
自2.10版本后,使用JsonReadFeature#ALLOW_TRAILING_COMMA代替

是否允许最后一个多余的逗号(一定是最后一个)。这个特征是非常重要的,若开关打开,有如下效果:

  • [true,true,]等价于[true, true]
  • {"a": true,}等价于{"a": true}

当这个特征和上面的ALLOW_MISSING_VALUES特征同时使用时,本特征优先级更高。也就是说:会先去除掉最后一个逗号后,再进行数组长度的计算。

举个例子:当然这两个特征开关都打开时,[true,true,]等价于[true, true]好理解;并且呢,[true,true,,]是等价于[true, true, null]的哦,可千万别忽略最后的这个null

@Test
public void test7() throws IOException {
    String jsonStr = "{\"results\" : [true,true,,] }";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        jsonParser.enable(JsonParser.Feature.ALLOW_MISSING_VALUES);
        // jsonParser.enable(JsonParser.Feature.ALLOW_TRAILING_COMMA);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("results".equals(fieldname)) {
                jsonParser.nextToken();

                while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
                    System.out.println(jsonParser.getBooleanValue());
                }
            }
        }
    }
}

运行程序,输出:

YourBatman
null
A哥
null
null

这完全就是上例的效果嘛。现在我放开注释掉的代码,再次运行,结果为:

YourBatman
null
A哥
null

请注意对比前后的结果差异,并自己能能自己合理解释

校验相关

Jackson在JSON标准之外,给出了两个校验相关的特征。

STRICT_DUPLICATE_DETECTION(false)
自2.10版本后,使用StreamReadFeature#STRICT_DUPLICATE_DETECTION代替

是否允许JSON串有两个相同的属性key,默认是允许的

@Test
public void test8() throws IOException {
    String jsonStr = "{\"age\":18, \"age\": 28 }";

    JsonFactory factory = new JsonFactory();
    try (JsonParser jsonParser = factory.createParser(jsonStr)) {
        // jsonParser.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);

        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jsonParser.getCurrentName();
            if ("age".equals(fieldname)) {
                jsonParser.nextToken();
                System.out.println(jsonParser.getIntValue());
            }
        }
    }
}

运行程序,正常输出:

18
28

若放开注释代码,再次运行,则抛错:

18 // 第一个数字还是能正常输出的哟

com.fasterxml.jackson.core.JsonParseException: Duplicate field ''age''
 at [Source: (String)"{"age":18, "age": 28 }"; line: 1, column: 17]
IGNORE_UNDEFINED(false)
自2.10版本后,使用StreamReadFeature#IGNORE_UNDEFINED代替

是否忽略没有定义的属性key。和JsonGenerator.Feature#IGNORE_UNKNOWN的这个特征一样,它作用于预先定义了格式的数据类型,如Avro、protobuf等等,JSON是不需要预先定义的哦~

同样的,你可以通过这个API预先设置格式:

JsonParser:

    public void setSchema(FormatSchema schema) {
        ...
    }

其它

INCLUDE_SOURCE_IN_LOCATION(true)
自2.10版本后,使用StreamReadFeature#INCLUDE_SOURCE_IN_LOCATION代替

是否构建JsonLocation对象来表示每个part的来源,你可以通过JsonParser#getCurrentLocation()来访问。作用不大,就此略过。

总结

本文介绍了底层流式API JsonParser读JSON的方式,它不仅仅能够处理标准JSON,也能通过Feature特征值来控制,开启对一些非标准但又比较常用的JSON串的支持,这不正式一个优秀框架/库应有的态度麽:兼容性

结合上篇文章对写JSON时JsonGenerator的描述,能够总结出两点原则:

  • 写:100%遵循规范
  • 读:最大程度兼容并包

写代表你的输出,遵循规范的输出能确保第三方在用你输出的数据时不至于对你破口大骂,所以这是你应该做好的本分。读代表你的输入,能够处理规范的格式是你的职责,但我若还能额外的处理一些非标准格式(一般为常用的),那绝对是闪耀点,也就是你给的情分。本分是你应该做的,而情分就是你的加分项。

相关推荐:
  • Fastjson到了说再见的时候了
  • 1. 初识Jackson -- 世界上最好的JSON库
  • 2. 妈呀,Jackson原来是这样写JSON的
  • 3. 懂了这些,方敢在简历上说会用Jackson写JSON

关注A哥

Author A哥(YourBatman)
个人站点 www.yourbatman.cn
E-mail yourbatman@qq.com
微 信 fsx641385712
活跃平台
公众号 BAT的乌托邦(ID:BAT-utopia)
知识星球 BAT的乌托邦
每日文章推荐 每日文章推荐

BAT的乌托邦

bash – 包含带有引号的多个args的变量

bash – 包含带有引号的多个args的变量

我生成一个包含所有我的args的bash变量,这些args包含空格。
当我用这些参数启动命令 – 例如。 ls $ args – 引号未正确解释。
这是一个例子 – 也创建和删除所需的文件。
#!/bin/bash
f1="file n1"
f2="file n2"
# create files
touch "$f1" "$f2"
# concatenate arguments
args="\"$f1\" \"$f2\""
# Print arguments,then launch 'ls' command
echo "arguments :" $args
ls $args
# delete files
rm "$f1" "$f2"

有了这个,“file,n1”,“file和n2”有一些“没有这样的文件”错误

您可以考虑使用 array作为参数,如下所示:
args=( "$f1" "$f2" )
ls "${args[@]}"

(您目前遇到的问题是,一旦内插发生,文件间空格和文件间空格之间就没有区别。)

Gson的JSON字符串:删除双引号

Gson的JSON字符串:删除双引号

这是我的Json代码的示例:

array("id" => 0, "navn" => "Vind telefon", "udgiver" => "Telia", "beskrivelse" => utf8_encode("Vind en Iphone 5 ved at gætte 1 spørgsmål"), "tilmeldte" => 89, "startdate" => "10-04-2013", "enddate" => "30-06-2013"),

如果我navn在程序中打印出该属性,则会得到以下输出:

"Vind Telefon"

如您所见,它保留了双引号。

有什么办法可以避免这种情况吗?

我的完整代码:

<?phpheader(''Content-Type: json; charset=utf-8'');$lottery = array(    array("id" => 0, "navn" => "Vind telefon", "udgiver" => "Telia", "beskrivelse" => utf8_encode("Vind en Iphone 5 ved at gætte 1 spørgsmål"), "tilmeldte" => 89, "startdate" => "10-04-2013", "enddate" => "30-06-2013"),    array("id" => 1, "navn" => "Fri taletid", "udgiver" => "Telmore", "beskrivelse" => utf8_encode("Vind et års forbrug af fri data og fri taletid"), "tilmeldte" => 701, "startdate" => "03-03-2013", "enddate" => "10-06-2013"),    array("id" => 2, "navn" => "Vind 5000 kr.", "udgiver" => "Bilka", "beskrivelse" => utf8_encode("Vind et gavekort på 5000 kr til bilka."), "tilmeldte" => 101, "startdate" => "10-05-2013", "enddate" => "01-07-2013"),    array("id" => 3, "navn" => "Fri vin", "udgiver" => "Føtex", "beskrivelse" => utf8_encode("Vind et års forbrug af vin"), "tilmeldte" => 391, "startdate" => "01-04-2013", "enddate" => "10-07-2013"),    array("id" => 4, "navn" => "Vind et TV", "udgiver" => "El-giganten", "beskrivelse" => utf8_encode("Vind et 60\" LED tv til stuen"), "tilmeldte" => 22, "startdate" => "01-04-2013", "enddate" => "22-07-2013"),    array("id" => 5, "navn" => "Vind en telefon", "udgiver" => "Samsung", "beskrivelse" => utf8_encode("Vind en Galaxy S4 4g telefon"), "tilmeldte" => 784, "startdate" => "10-04-2013", "enddate" => "30-07-2013"),    array("id" => 6, "navn" => "Gratis Vand", "udgiver" => "Aqua D''or", "beskrivelse" => utf8_encode("Vind et helt års forbrug af vand og dansk vand"), "tilmeldte" => 345, "startdate" => "01-03-2013", "enddate" => "18-07-2013"),    array("id" => 7, "navn" => "Fri Adwords", "udgiver" => "Google", "beskrivelse" => utf8_encode("Vind adwords kuponner til en værdi af 10.000"), "tilmeldte" => 22, "startdate" => "10-02-2013", "enddate" => "22-08-2013"),    array("id" => 8, "navn" => "Morgenmads produkter", "udgiver" => "Kellogs", "beskrivelse" => utf8_encode("Vind et helt års forbrug af kellogs produkter"), "tilmeldte" => 111, "startdate" => "01-05-2013", "enddate" => "10-09-2013"),    array("id" => 9, "navn" => utf8_encode("Vind tøj for 10.000"), "udgiver" => "Jack & Jones", "beskrivelse" => utf8_encode("Vind et gavekort til Jack & Jones på 10.000"), "tilmeldte" => 33, "startdate" => "03-05-2013", "enddate" => "01-10-2013"),);//id, navn, udgiver, beskrivelse, tilmeldte, startdate, slutdateecho json_encode($lottery);?>

java代码将其打印出来:

        String discription = arrayListing.get(i).getAsJsonObject().get("beskrivelse").toString();    System.out.println(discription);

我的完整Java代码

    public static void main(String[] args) {    String result = null;    BufferedReader reader = null;    try {        URL url = new URL("http://www.marcrasmussen.dk/json.php");        reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));        for (String line; (line = reader.readLine()) != null;) {            System.out.println(line);            result = line;        }    } catch (Exception e) {        e.printStackTrace();    } finally {        if (reader != null) {            try {                reader.close();            } catch (IOException e) {                // Ignore            }        }    }    JsonElement root = new JsonParser().parse(result);    HashMap<Integer,CompetetionObject> comMap = new HashMap<>();    JsonArray arrayListing = root.getAsJsonArray();    for (int i = 0; i < root.getAsJsonArray().size(); i++) {        int id = Integer.parseInt(arrayListing.get(i).getAsJsonObject().get("id").toString());        String name = arrayListing.get(i).getAsJsonObject().get("navn").toString();        String provider = arrayListing.get(i).getAsJsonObject().get("udgiver").toString();        String discription = arrayListing.get(i).getAsJsonObject().get("beskrivelse").toString();        int signedUp = Integer.parseInt(arrayListing.get(i).getAsJsonObject().get("tilmeldte").toString());        String startDate = arrayListing.get(i).getAsJsonObject().get("startdate").toString();        String endDate =  arrayListing.get(i).getAsJsonObject().get("enddate").toString();        CompetetionObject co = new CompetetionObject(id, name, provider, discription, signedUp, startDate, endDate);        String day = startDate.substring(1, 3);        String month = startDate.substring(5,6);        String year = startDate.substring(7,startDate.length()-1);        DateTime d = new DateTime(year+"-"+month+"-"+day);        System.out.println(discription);        comMap.put(id, co);    }}

我的Java程序的输出:

    [{"id":0,"navn":"Vind telefon","udgiver":"Telia","beskrivelse":"Vind en Iphone 5 ved at g\u00e6tte 1 sp\u00f8rgsm\u00e5l","tilmeldte":89,"startdate":"10-04-2013","enddate":"30-06-2013"},{"id":1,"navn":"Fri taletid","udgiver":"Telmore","beskrivelse":"Vind et \u00e5rs forbrug af fri data og fri taletid","tilmeldte":701,"startdate":"03-03-2013","enddate":"10-06-2013"},{"id":2,"navn":"Vind 5000 kr.","udgiver":"Bilka","beskrivelse":"Vind et gavekort p\u00e5 5000 kr til bilka.","tilmeldte":101,"startdate":"10-05-2013","enddate":"01-07-2013"},{"id":3,"navn":"Fri vin","udgiver":null,"beskrivelse":"Vind et \u00e5rs forbrug af vin","tilmeldte":391,"startdate":"01-04-2013","enddate":"10-07-2013"},{"id":4,"navn":"Vind et TV","udgiver":"El-giganten","beskrivelse":"Vind et 60\" LED tv til stuen","tilmeldte":22,"startdate":"01-04-2013","enddate":"22-07-2013"},{"id":5,"navn":"Vind en telefon","udgiver":"Samsung","beskrivelse":"Vind en Galaxy S4 4g telefon","tilmeldte":784,"startdate":"10-04-2013","enddate":"30-07-2013"},{"id":6,"navn":"Gratis Vand","udgiver":"Aqua D''or","beskrivelse":"Vind et helt \u00e5rs forbrug af vand og dansk vand","tilmeldte":345,"startdate":"01-03-2013","enddate":"18-07-2013"},{"id":7,"navn":"Fri Adwords","udgiver":"Google","beskrivelse":"Vind adwords kuponner til en v\u00e6rdi af 10.000","tilmeldte":22,"startdate":"10-02-2013","enddate":"22-08-2013"},{"id":8,"navn":"Morgenmads produkter","udgiver":"Kellogs","beskrivelse":"Vind et helt \u00e5rs forbrug af kellogs produkter","tilmeldte":111,"startdate":"01-05-2013","enddate":"10-09-2013"},{"id":9,"navn":"Vind t\u00f8j for 10.000","udgiver":"Jack & Jones","beskrivelse":"Vind et gavekort til Jack & Jones p\u00e5 10.000","tilmeldte":33,"startdate":"03-05-2013","enddate":"01-10-2013"}]"Vind en Iphone 5 ved at gætte 1 spørgsmål""Vind et års forbrug af fri data og fri taletid""Vind et gavekort på 5000 kr til bilka.""Vind et års forbrug af vin""Vind et 60\" LED tv til stuen""Vind en Galaxy S4 4g telefon""Vind et helt års forbrug af vand og dansk vand""Vind adwords kuponner til en værdi af 10.000""Vind et helt års forbrug af kellogs produkter""Vind et gavekort til Jack & Jones på 10.000"

答案1

小编典典

它的文档记录不正确,但是JsonElement#toString()会为您提供一个表示JSON元素的字符串,并且适合于重新创建JSON序列化。你想要的是JsonElement#getAsString()。如果您不查看字符串,这将引发错误,但是如果您查看字符串,则将获得字符串值。

这是一个演示程序:

import com.google.gson.JsonElement;import com.google.gson.JsonParser;public class Test {    public static void main(String[] args) {        String in = "{\"hello\":\"world\"}";        System.out.println(in);        JsonElement root = new JsonParser().parse(in);        System.out.println(root.getAsJsonObject().get("hello").toString());        System.out.println(root.getAsJsonObject().get("hello").getAsString());    }}

及其输出:

{"hello":"world"}"world"world

Java - 手动解析不带引号的JSON字符串

Java - 手动解析不带引号的JSON字符串

[TOC]

1 需求说明

项目中遇到了一批不带引号的类JSON格式的字符串:

{Name:Heal,Age:20,Tag:[Coding,Reading]}

需要将其解析成JSON对象, 然后插入到Elasticsearch中, 当作Object类型的对象存储起来.

在对比了阿里的FastJson、Google的Gson, 没找到想要的功能 ( 可能是博主不够仔细, 有了解的童学留言告诉我下呀), 于是就自己写了个工具类, 用来实现此需求.

如果是带有引号的标准JSON字符串, 可直接通过上述2种工具进行解析, 使用方法可参考: Java - 格式化输出JSON字符串的两种方式

2 解析代码

2.1 实现思路

代码的主要思路在注释中都有说明, 主要思路是:

(1) 借助Stack统计字符串首尾的[]、{}符号 —— []代表List, {}代表Map;

(2) 使用String#subString()方法缩减已解析的字符串;

(3) 使用递归解析内部的List、Map对象;

(4) 为了便于处理, 最小的key-value都解析成String类型.

需要注意的是: 要解析的字符串内部不要存在无意义的{、}、[、]符号, 否则会导致解析发生异常. —— 暂时没想到好的兼容方法, 有想法的童学请直接留言.**

2.2 详细代码

package com.healchow.util;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * Java 解析不带引号的JSON字符串
 *
 * @author Heal Chow
 * @date 2019/08/13 11:36
 */
public class ParseJsonStrUtils {

    public static void main(String[] args) {

        // 带引号的字符串, 会将字符串当作key-value的一部分, 因此这类字符串推荐使用fastJson、Gson等工具转换
        // 注意: String内部不要存在无意义的{、}、[、]符号 - 暂时没想到好的兼容方法
        /*String sourceStr = "{\"_index\":\"book_shop\"," +
                           "\"_id\":\"1\"," +
                           "\"_source\":{" +
                               "\"name\":\"Thinking in Java [4th Edition]\"," +
                               "\"author\":\"[US] Bruce Eckel\"," +
                               "\"price\":109.0,\"date\":\"2007-06-01 00:00:00\"," +
                               "\"tags\":[\"Java\",[\"Programming\"]" +
                           "}}";*/

        // 不带引号的字符串, 首尾多对[]、{}不影响解析
        String sourceStr = "[[[{" +
                            "{" +
                                "Type:1," +
                                "StoragePath:[{Name:/image/2019-08-01/15.jpeg,DeviceID:4401120000130},{ShotTime:2019-08-01 14:44:24}]," +
                                "Width:140" +
                            "}," +
                            "{" +
                                "Type:2,StoragePath:9090/pic/2019_08_01/src.jpeg," +
                                "Inner:{DeviceID:44011200}," +
                                "Test:[{ShotTime:2019-08-01 14:50:14}]," +
                                "Width:5600}" +
                            "}}]]]";

        List<Map<String, Object>> jsonArray;
        Map<String, Object> jsonMap;

        Object obj = null;
        try {
            obj = parseJson(sourceStr);
        } catch (Exception e) {
            System.out.println("出错啦: " + e.getMessage());
            e.printStackTrace();
        }

        if (obj instanceof List) {
            jsonArray = (List<Map<String, Object>>) obj;
            System.out.println("解析生成了List对象: " + jsonArray);
        } else if (obj instanceof Map) {
            jsonMap = (Map<String, Object>) obj;
            System.out.println("解析生成了Map对象: " + jsonMap);
        } else {
            System.out.println("需要解析的字符串既不是JSON Array, 也不符合JSON Object!\n原字符串: " + sourceStr);
        }
    }

    /**
     * 解析 Json 格式的字符串, 封装为 List 或 Map 并返回
     * 注意: (1) key 和 value 不能含有 ",", key 中不能含有 ":" —— 要分别用 "," 和 ":" 进行分隔
     *      (2) 要解析的字符串必须符合JSON对象的格式, 只对最外层的多层嵌套做了简单的处理,
     *          复杂的如"{a:b},{x:y}"将不能完全识别 —— 正确的应该是"[{a:b},{x:y}]"
     * @param sourceStr 首尾被"[]"或"{}"包围的字符串
     * @return 生成的JsonObject
     */
    public static Object parseJson(String sourceStr) throws InvalidParameterException {
        if (sourceStr == null || "".equals(sourceStr)) {
            return sourceStr;
        }

        // 判断字符串首尾有没有多余的、相匹配的 "[]" 和 "{}"
        String parsedStr = simplifyStr(sourceStr, "[", "]");
        parsedStr = simplifyStr(parsedStr, "{", "}");

        // 借助栈来实现 "[]" 和 "{}" 的出入
        Stack<String> leftSymbolStack = new Stack<>();
        Stack<String> rightSymbolStack = new Stack<>();

        if ((parsedStr.startsWith("[") && parsedStr.endsWith("]")) || (parsedStr.startsWith("{") && parsedStr.endsWith("}"))) {
            leftSymbolStack.push(parsedStr.substring(0, 1));
            rightSymbolStack.push(parsedStr.substring(parsedStr.length() - 1));
            parsedStr = parsedStr.substring(1, parsedStr.length() - 1);

            // parsedStr 内部还可能是连续的"{{}}"
            parsedStr = simplifyStr(parsedStr, "{", "}");
        } else {
            throw new InvalidParameterException("要解析的字符串中存在不匹配的''[]''或''{}'', 请检查!\n原字符串为: " + sourceStr);
        }

        // 保存解析的结果, jsonArray中可能只有String, 也可能含有Map<String, Object>
        List<Object> jsonArray = new ArrayList<>();
        Map<String, Object> jsonMap = new HashMap<>(16);

        // 内部遍历、解析
        innerParseByLoop(parsedStr, leftSymbolStack, rightSymbolStack, jsonArray, jsonMap);

        // 判断jsonArray是否为空
        if (jsonArray.size() > 0) {
            return jsonArray;
        } else {
            return jsonMap;
        }
    }

    /**
     * 循环解析内部的List、Map对象
     */
    private static void innerParseByLoop(String parsedStr, Stack<String> leftSymbolStack, Stack<String> rightSymbolStack,
                                         List<Object> jsonArray, Map<String, Object> jsonMap) throws InvalidParameterException {
        if (parsedStr == null || parsedStr.equals("")) {
            return;
        }
        // 按照","分隔
        String[] allKeyValues = parsedStr.split(",");
        if (allKeyValues.length > 0) {

            // 遍历, 并按照":"分隔解析
            out:
            for (String keyValue : allKeyValues) {

                // 如果keyValue中含有":", 说明该keyValue是List<Map>中的一个对象, 就需要确定第一个":"的位置 —— 可能存在多个":"
                int index = keyValue.indexOf(":");
                if (index > 0) {

                    // 判断key是否仍然以"{"或"["开始, 如果是, 则压栈
                    String key = keyValue.substring(0, index);
                    while (key.startsWith("[") || key.startsWith("{")) {
                        leftSymbolStack.push(key.substring(0, 1));
                        // 解析过的串要一直跟进
                        parsedStr = parsedStr.substring(1);
                        key = key.substring(1);
                    }

                    // 判读和value是否以"["开头 —— 又是一个 List 对象 —— 递归解析
                    String value = keyValue.substring(index + 1);
                    if (value.startsWith("[")) {
                        int innerIndex = parsedStr.indexOf("]");
                        List<Object> innerList = (List<Object>) parseJson(parsedStr.substring(key.length() + 1, innerIndex + 1));
                        jsonMap.put(key, innerList);
                        // 清除最后的"]", 并判断是否存在","
                        parsedStr = parsedStr.substring(innerIndex + 1);
                        if (parsedStr.indexOf(",") == 0) {
                            parsedStr = parsedStr.substring(1);
                        }

                        // 此内部存在对象, 内部的","已经解析完毕了, 要修正按照","切割的字符串数组, 并继续遍历
                        innerParseByLoop(parsedStr, leftSymbolStack, rightSymbolStack, jsonArray, jsonMap);
                        break;
                    }

                    // 判读和value是否以 "{" 开头 —— 又是一个 Map 对象 —— 递归解析
                    else if (value.startsWith("{")) {
                        int innerIndex = parsedStr.indexOf("}");
                        Map<String, Object> innerMap = (Map<String, Object>) parseJson(parsedStr.substring(key.length() + 1, innerIndex + 1));
                        jsonMap.put(key, innerMap);

                        // 清除最后的"}", 并判断是否存在","
                        parsedStr = parsedStr.substring(innerIndex + 1);
                        if (parsedStr.indexOf(",") == 0) {
                            parsedStr = parsedStr.substring(1);
                        }

                        // 此内部存在对象, 内部的","已经解析完毕了, 要修正按照","切割的字符串数组, 并继续遍历
                        innerParseByLoop(parsedStr, leftSymbolStack, rightSymbolStack, jsonArray, jsonMap);
                        break;
                    }

                    // 最后判断value尾部是否含有 "]" 或 "}"
                    else {
                        while (value.endsWith("]") || value.endsWith("}")) {
                            // 最右侧的字符
                            String right = value.substring(value.length() - 1);
                            // 此时栈顶元素
                            String top = leftSymbolStack.peek();
                            // 如果有相匹配的, 则弹栈, 否则忽略
                            if (("}".equals(right) && "{".equals(top)) || ("]".equals(right) && "[".equals(top))) {
                                leftSymbolStack.pop();
                                value = value.substring(0, value.length() - 1);
                                jsonMap.put(key, value);

                                // 清除最后的"}", 并判断是否存在","
                                parsedStr = parsedStr.substring(key.length() + 1 + value.length() + 1);
                                if (parsedStr.indexOf(",") == 0) {
                                    parsedStr = parsedStr.substring(1);
                                }

                                // 解析完成了一个对象, 则将该元素添加到List中, 并创建新的对象
                                jsonArray.add(jsonMap);
                                jsonMap = new HashMap<>(16);

                                // 继续进行外层的解析
                                continue out;
                            }

                            // 如果都不匹配, 则有可能是源字符串的最后一个符号
                            else {
                                rightSymbolStack.push(right);
                                value = value.substring(0, value.length() - 1);
                            }
                        }
                        jsonMap.put(key, value);
                        int length = key.length() + value.length() + 2;
                        if (parsedStr.length() > length) {
                            parsedStr = parsedStr.substring(length);
                        } else {
                            parsedStr = "";
                        }
                    }
                }
                // 如果keyValue中不含":", 说明该keyValue只是List<String>中的一个串, 而非List<Map>中的一个Map, 则直接将其添加到List中即可
                else {
                    jsonArray.add(keyValue);
                }
            }

            // 遍历结束, 处理最后的符号问题 —— 判断左右栈是否匹配
            while (!leftSymbolStack.empty()) {
                if (leftSymbolStack.peek().equals("{") && parsedStr.equals("}")) {
                    leftSymbolStack.pop();
                }
                if (!rightSymbolStack.empty()) {
                    if (leftSymbolStack.peek().equals("{") && rightSymbolStack.peek().equals("}")) {
                        leftSymbolStack.pop();
                        rightSymbolStack.pop();
                    } else if (leftSymbolStack.peek().equals("[") && rightSymbolStack.peek().equals("]")) {
                        leftSymbolStack.pop();
                        rightSymbolStack.pop();
                    } else {
                        throw new InvalidParameterException("传入的字符串中不能被解析成JSON对象!\n原字符串为: " + parsedStr);
                    }
                }
            }
        }
    }

    /**
     * 判断字符串首尾有没有多余的、相匹配的 "[]" 和 "{}", 对其进行简化
     */
    private static String simplifyStr(String sourceStr, String firstSymbol, String lastSymbol) {

        while (sourceStr.startsWith(firstSymbol) && sourceStr.endsWith(lastSymbol)) {
            String second = sourceStr.substring(1, 2);
            // 如果第二个仍然是"["或"{", 再判断倒数第二个是不是"]"或"}" —— 说明长度至少为3, 不会发生 IndexOutOfBoundsException
            if (second.equals(firstSymbol)) {
                String penultimate = sourceStr.substring(sourceStr.length() - 2, sourceStr.length() - 1);
                if (penultimate.equals(lastSymbol)) {
                    // 缩短要解析的串
                    sourceStr = sourceStr.substring(1, sourceStr.length() - 1);
                } else {
                    break;
                }
            } else {
                break;
            }
        }
        return sourceStr;
    }

}

2.3 测试样例

(1) 带引号的测试:

// 测试字符串:
String sourceStr = "{\"_index\":\"book_shop\"," +
                   "\"_id\":\"1\"," +
                   "\"_source\":{" +
                       "\"name\":\"Thinking in Java [4th Edition]\"," +
                       "\"author\":\"[US] Bruce Eckel\"," +
                       "\"price\":109.0,\"date\":\"2007-06-01 00:00:00\"," +
                       "\"tags\":[\"Java\",[\"Programming\"]" +
                   "}}";

解析结果为: <img src="https://img2018.cnblogs.com/blog/1438655/201908/1438655-20190820124256767-682854686.jpg" width="65%" alt="字符串解析结果-带引号" />

(2) 不带引号的测试:

// 测试字符串: 
String sourceStr = "[[[{" +
                    "{" +
                        "Type:1," +
                        "StoragePath:[{Name:/image/2019-08-01/15.jpeg,DeviceID:4401120000130},{ShotTime:2019-08-01 14:44:24}]," +
                        "Width:140" +
                    "}," +
                    "{" +
                        "Type:2,StoragePath:9090/pic/2019_08_01/src.jpeg," +
                        "Inner:{DeviceID:44011200}," +
                        "Test:[{ShotTime:2019-08-01 14:50:14}]," +
                        "Width:5600}" +
                    "}}]]]";

解析结果为:

<img src="https://img2018.cnblogs.com/blog/1438655/201908/1438655-20190820124345323-1941086699.jpg" width="65%" alt="字符串解析结果-不带引号" />

<br/>

版权声明

出处: 博客园 瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 如果文章有帮助或启发到你, 点个[<a href="javascript:void(0);" onclick="DiggIt(11382231,cb_blogId,1);green_channel_success(this,''谢谢推荐'');">好文要顶</a>] 或 [<a href="javascript:void(0);" onclick="votePost(11382231,''Digg'')">推荐</a>] 吧

本文版权归博主所有, 欢迎转载, 但 [必须在文章页面明显位置标明原文链接], 否则博主保留追究相关人员法律责任的权利.

原文出处:https://www.cnblogs.com/shoufeng/p/11382231.html

关于带有引号的JSON.parse字符串带引号的json字符串传前台的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于4. JSON字符串是如何被解析的?JsonParser了解一下、bash – 包含带有引号的多个args的变量、Gson的JSON字符串:删除双引号、Java - 手动解析不带引号的JSON字符串的相关信息,请在本站寻找。

本文标签: