如何使用Jackson将十六进制颜色数组反序列化为awt.Color对象
问题根因
你之前对JsonParser的使用没有问题,报错本质是自定义反序列化器没有生效,Jackson尝试用默认规则构造java.awt.Color对象失败,叠加字段匹配问题,具体错误点如下:
- 容器类反序列化注解配置错误:你要反序列化的是
Color[]数组中的每个元素,不是数组本身,不能直接用@JsonDeserialize(using = xxx),需要用contentUsing参数指定容器内元素的反序列化器 - POJO字段与JSON字段不匹配:JSON返回的字段名为
palette,你最初定义的POJO字段名为colorPalette,Jackson无法自动匹配,要么修改字段名保持一致,要么通过@JsonProperty("palette")手动指定映射关系 - 补充说明:
Color.decode()本身支持处理带#的十六进制颜色字符串,你最终选择手动截取#后转成无符号整数构造Color的方案也是完全可用的,两种写法都可正常运行
最终可运行实现方案
1. 修正POJO配置
匹配JSON字段名,同时为数组配置元素级别的反序列化器:
public class PanelInfo { // 其他类成员 @JsonDeserialize(contentUsing = ColorJsonDeserializer.class) private Color[] palette; // getter、setter方法 }
如果不想修改原有字段名,也可以通过@JsonProperty做字段映射:
public class PanelInfo { // 其他类成员 @JsonProperty("palette") @JsonDeserialize(contentUsing = ColorJsonDeserializer.class) private Color[] colorPalette; // getter、setter方法 }
2. 自定义反序列化器实现
两种写法均经过验证可正常运行,可根据需求选择:
写法1:手动截取#转16进制整数构造
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.awt.Color; import java.io.IOException; public class ColorJsonDeserializer extends JsonDeserializer<Color> { @Override public Color deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String colorStr = p.getValueAsString(); // 去掉颜色字符串开头的#,转16进制无符号整数构造Color对象 return new Color(Integer.parseUnsignedInt(colorStr.substring(1), 16)); } }
写法2:直接调用Color.decode解析
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.awt.Color; import java.io.IOException; public class ColorJsonDeserializer extends JsonDeserializer<Color> { @Override public Color deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { return Color.decode(p.getValueAsString()); } }
内容的提问来源于stack exchange,提问作者Scaddenp
相关产品推荐
相关产品推荐

