
Jackson 默认会将形如 "5 ttt" 的未加引号输入尝试按数值类型解析,导致 readValue("5 ttt", Type.class) 失败或截断;正确做法是确保原始输入为合法 JSON 字符串——即用双引号包裹,例如 "\"5 ttt\"".
jackson 默认会将以数字开头的字符串(如 "5 ttt")误判为数值字面量并尝试解析为整数,从而在调用 readvalue("5 ttt", testclass.class) 时仅提取出 "5" 或直接抛出异常。根本原因在于 jackson 要求输入必须是合法 json;而裸字符串 5 ttt 不符合 json 规范,解析器会按“松散模式”试探性匹配最可能的类型(如 number),而非字符串。
要使 Jackson 正确将整个内容作为字符串处理,输入必须是有效的 JSON 字符串字面量,即用双引号包裹:
TestClass testClass = mapper2.readValue("\"5 ttt\"", TestClass.class);
此时 Jackson 明确识别该 token 为 JSON 字符串(JsonToken.VALUE_STRING),你的自定义 JsonDeserializer 中调用 p.getValueAsString() 就能完整获取 "5 ttt"。
⚠️ 注意:若原始数据来自外部(如日志、表单、配置文件),它大概率不是合法 JSON。你不能直接传入裸字符串,而应预处理为标准 JSON 字符串。以下是一个安全的封装工具方法:
private static String wrapAsJsonString(String value) throws JsonProcessingException {
if (value == null) return "\"\"";
// 检查是否已为合法带引号的 JSON 字符串(避免嵌套引号)
if (value.length() >= 2 &&
value.startsWith("\"") &&
value.endsWith("\"") &&
!value.substring(1, value.length() - 1).contains("\"")) {
return value;
}
return new ObjectMapper().writeValueAsString(value);
}
使用示例:
String rawInput = "5 ttt"; String jsonSafe = wrapAsJsonString(rawInput); // → "\"5 ttt\"" TestClass obj = mapper2.readValue(jsonSafe, TestClass.class); System.out.println(obj.field); // 输出:5 ttt
✅ 关键总结:
- Jackson 不支持“模糊字符串解析”;它严格遵循 JSON 规范。
-
@JsonDeserialize对类级反序列化生效,但前提是输入语法合法;非法输入会在进入 deserializer 前就被JsonParser截断或报错。 - 不要试图通过字段级
@JsonDeserialize绕过语法问题——根源在输入格式,而非类型绑定逻辑。 - 生产环境中,所有非结构化字符串输入都应经
ObjectMapper#writeValueAsString()安全转义后再用于readValue,这是保障 JSON 合法性的黄金实践。










