You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot接收含特殊字符的JSON对象解析报错,寻求解决方法

问题描述

我开发了一个SpringBoot应用,接收包含字符串、嵌套对象及数组的JSON格式请求体。当嵌套对象的字符串字段包含逗号、冒号、斜杠时,会出现解析错误。我理解这些字符是JSON解析的关键字符,会干扰转换过程,请问有解决办法吗?

我的代码

public String setProperties(@RequestBody Map<String, Object> body) throws JSONException {
        logger.info("->"+ body); 
        System.out.println(body);
        
        String id = body.get("id").toString();
        String name = body.get("name").toString();
        JSONArray props = new JSONArray(body.get("properties").toString());

请求对象示例

{
    "id":4,
    "name":"test",
    "properties":[{
        "house":{"address":"elm street, 2", // 此逗号导致错误
            "postcode":"000012",
            "area":"001"
        },
        "code":"XXX",
        "lng":"40.3895",
        "created":"2022-04-06:T0:818000200", // 此冒号也会引发错误
   }]
}

报错信息

Expected a ':' after a key at character 43
    at org.json.JSONTokener.syntaxError(JSONTokener.java:410)
    at org.json.JSONObject.<init>(JSONObject.java:203)
    at org.json.JSONTokener.nextValue(JSONTokener.java:344)
    at org.json.JSONObject.<init>(JSONObject.java:205)
    at org.json.JSONTokener.nextValue(JSONTokener.java:344)
    at org.json.JSONArray.<init>(JSONArray.java:125)
    at org.json.JSONArray.<init>(JSONArray.java:157)
解决方法

问题根源:你把Spring已经正确解析好的Map对象转成字符串,再用org.json库二次解析,这完全是多余操作,而且Map的toString()输出不是标准JSON格式,会破坏嵌套结构的语法规则,导致解析失败。

方法1:直接使用Spring解析后的对象,避免二次解析

Spring的@RequestBody已经把请求体完整解析为Map<String, Object>,其中properties本身就是List类型,直接强转即可使用,不需要再用org.json处理:

public String setProperties(@RequestBody Map<String, Object> body) {
    logger.info("->"+ body); 
    System.out.println(body);
    
    String id = body.get("id").toString();
    String name = body.get("name").toString();
    // 直接强转为List,跳过org.json的二次解析
    List<Map<String, Object>> props = (List<Map<String, Object>>) body.get("properties");
    
    // 处理嵌套对象中的特殊字符字段
    for (Map<String, Object> prop : props) {
        Map<String, Object> house = (Map<String, Object>) prop.get("house");
        String address = house.get("address").toString(); // 包含逗号的字符串可正常获取
        String created = prop.get("created").toString(); // 包含冒号的字符串可正常获取
        // 后续业务逻辑处理
    }
    return "success";
}

方法2:定义实体类接收请求(更推荐)

创建对应结构的实体类,让Spring直接将JSON映射为实体对象,代码更清晰、类型安全,无需强制转换:

// 顶层请求实体类
public class RequestBodyDTO {
    private Integer id;
    private String name;
    private List<Property> properties;
    
    // 生成Getter和Setter方法
}

// Property实体类
public class Property {
    private House house;
    private String code;
    private String lng;
    private String created;
    
    // 生成Getter和Setter方法
}

// House实体类
public class House {
    private String address;
    private String postcode;
    private String area;
    
    // 生成Getter和Setter方法
}

修改控制器方法:

public String setProperties(@RequestBody RequestBodyDTO requestDTO) {
    logger.info("->"+ requestDTO); 
    System.out.println(requestDTO);
    
    String id = requestDTO.getId().toString();
    String name = requestDTO.getName();
    List<Property> props = requestDTO.getProperties();
    
    for (Property prop : props) {
        String address = prop.getHouse().getAddress();
        String created = prop.getCreated();
        // 业务逻辑处理
    }
    return "success";
}

补充说明

字符串中的逗号、冒号本身是JSON允许的合法内容,只要请求体是标准JSON格式(你的请求示例是符合标准的),Spring的默认解析器(Jackson)就能正确处理。原代码的错误完全是因为二次解析的多余操作导致的,和字符串中的特殊字符无关。

内容的提问来源于stack exchange,提问作者arnau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:20:34