Java解析YAML时JSON结构字段转String类型报错问题排查
问题原因
Jackson的YAML解析器会把YAML中的{}结构识别为对象类型,但你的Java类A中field3定义为String类型,类型不匹配导致抛出MismatchedInputException。
简单来说:YAML里的field3: {"x":"apple"...}被解析成了JSON对象,而你需要把这段内容当成字符串存入field3,两者类型不兼容。
解决方案
提供三种可行的解决方式,按需选择:
方式一:修改YAML文件,将JSON对象转为字符串
把field3的内容用引号包裹,让YAML解析器识别为字符串:
- field1: 2022-12-23T21:45:26.097+01 field2: true field3: '{"x":"apple", "y": { "z":10, "w":[{ "a": 11}]}}'
注:YAML中单引号内部的双引号不需要转义;用双引号的话需要转义内部的双引号,例如"{\"x\":\"apple\"}"
方式二:使用Jackson注解@JsonRawValue(推荐)
无需修改YAML,直接在Java类的field3字段上添加@JsonRawValue注解,让Jackson将对应的YAML对象直接序列化为原始JSON字符串:
class A{ int field1; boolean field2; @JsonRawValue String field3; }
这个注解会告诉Jackson:把该字段对应的JSON/YAML节点直接以原始字符串形式赋值给String变量,无需解析为对象。
方式三:自定义反序列化器
如果需要更灵活的处理逻辑,可以自定义一个反序列化器,将YAML对象转换为JSON字符串:
- 实现反序列化器:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; public class JsonObjectToStringDeserializer extends StdDeserializer<String> { public JsonObjectToStringDeserializer() { super(String.class); } @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.readValueAsTree(); return node.toString(); } }
- 在
field3字段上关联该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; class A{ int field1; boolean field2; @JsonDeserialize(using = JsonObjectToStringDeserializer.class) String field3; }
额外注意
你的YAML文件开头有个减号-,表示这是一个列表项,所以解析时要确保目标类型是List<A>或者A[],例如:
List<A> list = mapper.readValue(file, new TypeReference<List<A>>() {});
内容的提问来源于stack exchange,提问作者HowToTellAChild
相关产品推荐
相关产品推荐

