问题背景

最近在使用 Fastjson(版本 1.1.38)序列化对象时,遇到了java.lang.ArrayIndexOutOfBoundsException: 160异常,堆栈指向SerializeWriter.writeFieldValueStringWithDoubleQuote方法。初步怀疑是对象 “长度太长”,但深入分析后发现,问题根源与 Fastjson 旧版本的序列化逻辑缺陷、前端 URL 参数未正确编码密切相关。本文结合权威资料与实践经验,总结完整排查思路与解决方案。

 
 

异常核心原因分析

异常本质是 Fastjson 内部字符缓冲区溢出。Fastjson 1.1.38 作为 2014 年的极旧版本,其SerializeWriter类在处理字符串序列化时,使用固定大小的字符数组(如默认 1024)作为缓冲区。当遇到以下场景时,缓冲区索引会越界:

 
1. 后端:Fastjson 旧版本的序列化缺陷
  • 特殊字符未处理:若对象字段包含控制字符(如\u0000空字符)、未转义的\",Fastjson 旧版本无法正确计算缓冲区写入位置,导致索引越界。
  • 复杂对象结构:嵌套对象、数组或集合的递归序列化可能触发索引计算错误(如数组长度未校验)。
 
2. 前端:URL 参数未编码传递

前端传递参数时,若 URL 中包含特殊字符(如&、空格、中文)未用encodeURIComponent编码,后端接收参数时可能因解析错误(如&被识别为参数分隔符),导致字段值不完整或格式错误,间接触发 Fastjson 序列化异常。

 
 

多维度解决方案(前端 + 后端)

方案 1:前端对 URL 参数编码(关键预防)

前端传递参数前,需用encodeURIComponent对参数值编码,将特殊字符转换为%XX形式(如空格→%20&%26),避免后端解析错误。

 

示例(JavaScript)

 

javascript

// 前端传递参数时编码
const paramValue = "测试&特殊字符 空格#";
const encodedValue = encodeURIComponent(paramValue); 
// 编码结果:"测试%26特殊字符%20空格%23"
const url = `http://api.example.com/query?param=${encodedValue}`;
 
方案 2:后端升级 Fastjson 版本(最有效)

Fastjson 1.2.6 + 版本优化了SerializeWriter的动态扩容逻辑(自动根据内容调整缓冲区大小),2.0.x 版本彻底重构序列化引擎,修复了缓冲区溢出问题。

 

Maven 依赖(推荐)

 

xml

<!-- 1.x稳定版(兼容旧代码) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>

<!-- 2.x新版(性能更优) -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.25</version>
</dependency>
 
方案 3:清理或转义特殊字符(兼容旧版本)

若无法升级 Fastjson,需检查对象字段是否包含特殊字符(如控制字符\u0000-\u001F),序列化前清理或转义。

 

示例(Java)

 

java

public class TBean {
    private String content;

    // 清理控制字符(保留可打印字符)
    public String getCleanContent() {
        if (content == null) return null;
        return content.replaceAll("[\\u0000-\\u001F]", ""); 
    }
}

// 序列化时使用清理后的字段
String json = JSON.toJSONString(tBean.getCleanContent());
 
方案 4:调整序列化配置(辅助手段)

通过SerializerFeature调整序列化行为,减少缓冲区压力:

 

java

// 禁用循环引用检测(降低递归复杂度),强制非字符串值转字符串
String json = JSON.toJSONString(tBean, 
    SerializerFeature.DisableCircularReferenceDetect, 
    SerializerFeature.WriteNonStringValueAsString
);
 
方案 5:替换为其他 JSON 库(终极备选)

若 Fastjson 问题仍无法解决,可替换为 Jackson 或 Gson(对复杂对象和特殊字符兼容性更好)。

 

Jackson 示例

 

java

ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(tBean); // 直接序列化对象
 
 

总结

ArrayIndexOutOfBoundsException的核心是 Fastjson 1.1.38 的序列化缓冲区缺陷,前端 URL 未编码可能触发或加剧此问题。
最优组合方案:前端用encodeURIComponent编码参数 + 后端升级 Fastjson 到 1.2.83+/2.0.25+,可 99% 以上避免此类异常。若需兼容旧环境,需结合字段清理或替换 JSON 库。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐