Jackson 反序列化 "Y"/"N" 为相应的布尔值
JSON 表示布尔值标准的形式是 true 和 false,如果 Java 对应的类型是对象 Boolean,那么在 JSON 中也可以是 null。如果收到 JSON 数据是用 'Y'/'N', 或 'Yes'/'No' 来表示布尔值的,那么使用 Java 的 Jackson 库如何把它们反序列化为相应的布尔属性值呢?
如果按照 JSON 规范必须把内容中的布尔值全部转换为 true 或 false, 然而再反序列化,否则需要定制 Boolean 类型的反序列化类,可应用到全局的 boolean 类型,或指派给特定的 boolean 类型属性。
如果尝试反序列化 Y, 或 N 为 Java 的 boolean 值,会有只接受 true 或 false 的异常:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.lang.Boolean from String "Y": only "true" or "false" recognized
具体步骤是:
先创建一个 YNBooleanDeserializer 类
1package blog.yanbin.jsonutils;
2
3import com.fasterxml.jackson.core.*;
4import com.fasterxml.jackson.databind.*;
5import java.io.IOException;
6
7public class YNBooleanDeserializer extends JsonDeserializer<Boolean> {
8
9 @Override
10 public Boolean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
11 JsonToken currentToken = jp.getCurrentToken();
12
13 if (currentToken.equals(JsonToken.VALUE_STRING)) {
14 String text = jp.getText();
15
16 if ("Y".equals(text)) {
17 return Boolean.TRUE;
18 } else if ("N".equals(text)) {
19 return Boolean.FALSE;
20 }
21
22 throw ctxt.weirdStringException(text, Boolean.class,
23 "Only \"" + YES + "\" or \"" + NO + "\" values supported");
24 } else if (currentToken.equals(JsonToken.VALUE_NULL)) {
25 return Boolean.FALSE;
26 //return null
27 }
28
29 throw ctxt.mappingException("Can't parse boolean value: " + jp.getText());
30 }
31}应用到相应的 Boolean 属性上
1class User {
2
3 @JsonDeserialize(using = YNBooleanDeserializer.class)
4 public Boolean isAlive;
5}测试代码
1ObjectMapper objectMapper = new ObjectMapper() ;
2String json = "{\"isAlive\":\"Y\"}";
3User user = objectMapper.readValue(json, User.class);
4System.out.println(user.isAlive);可以得到 user.isAlive 属性值为 true。
其他问题引申
上面代码只是给某些个别的属性使用 YNBooleanDeserializer 来反序列化 JSON 中的 boolean 值,如果 JSON 中全部的 boolean 值都是用 Y/N 来表示的,那么可以为 ObjectMapper 注册一个模块,完整代码如下:
1ObjectMapper objectMapper = new ObjectMapper() ;
2
3SimpleModule boolModule = new SimpleModule();
4boolModule.addDeserializer(Boolean.class, new YNBooleanDeserializer());
5objectMapper.registerModule(boolModule);
6
7String json = "{\"isAlive\":\"Y\"}";
8User user = objectMapper.readValue(json, User.class);
9System.out.println(user.isAlive);这时候在 User 中就不需要 JsonDeserialize(using = YNBooleanDeserializer.class) 注解了。
再一步引申,如果希望序列化时也用 Y/N 来表示 boolean 值,可用的方法与上面差不多,只是反着方向来的。比如特定属性上用
@JsonSerialize(using = YBNooleanSerializer.class)
或是全局的模块中设定
booleanModule.addSerializer(Boolean.class, new YNBooleanSerializer());
具体代码不再一一列出了,请参考上面的代码实现。
永久链接 https://yanbin.blog/jackson-yn-boolean-value-deserialization/, 来自 隔叶黄莺 Yanbin's Blog[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。