本文概览:当json字符串中新增了两个字段,但是对应的Object没有新增成员,此时将json转成Object时报错了。
1 问题引入
数据表pay_ticket中一个recv_info,保存的是json字符串(如下),并且有一个RecvInfo类与之对应(有3个成员:bankUserId、amount、bankName)。
1 |
[{"bankUserId":"4005","amount":2800,"bankName":"邮储银行"}] |
此时有个需求,在上面json中新增一个“frontBankCode”字段(如下),并且在RecvInfo类中也新增一个frontBankCode成员。
1 |
[{"bankUserId":"4005","amount":2800,"bankName":"邮储银行","frontBankCode":"4005"}] |
进行发布时,假设在机器1部署了代码,但是机器2上还没有部署:
- 首先,有请求通过机器1写入recv_info字段的值,此时包含frontBankCode的字段;
- 然后,有请求到了机器2上去读取这个字段的值,并转换成对象RecvInfo,因为recv_info中有frontBankCode,但是机器2上的代码还是之前的,即此时RecvInfo类中没有成员frongBankCode,此时抛异常出错。
2 复现问题
1、定义RecvInfo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class RecvInfo { private String bankUserId; private Long amount; private String bankName; public String getBankUserId() { return bankUserId; } public void setBankUserId(String bankUserId) { this.bankUserId = bankUserId; } public Long getAmount() { return amount; } public void setAmount(Long amount) { this.amount = amount; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE); } } |
2、进行解析
当把如下json解析成RecvInfo对象,此时json比RecvInfo多了一个frontBankCode字段信息。
1 |
[{"bankUserId":"4005","amount":2800,"bankName":"邮储银行","frontBankCode":"4005"}] |
对应的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class FastJsonTest { public List<RecvInfo> prase(String recvInfo) throws IOException{ if (StringUtils.isBlank(recvInfo)) { return null; } ObjectMapper mapper = new ObjectMapper(); com.fasterxml.jackson.databind.JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, RecvInfo.class); return (List<RecvInfo>) mapper.readValue(recvInfo, javaType); } public static void main(String[] args) throws IOException{ String inputNew = "[{\"bankUserId\":\"4005\",\"amount\":2800,\"bankName\":\"邮储银行\",\"frontBankCode\":\"4005\"}]"; FastJsonTest fastJsonTest = new FastJsonTest(); List<RecvInfo> result = fastJsonTest.prase(inputNew); System.out.println(result.toString()); } } |
执行结果为
Exception in thread “main” com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field “frontBankCode” (class json.RecvableRecvInfo), not marked as ignorable (3 known properties: “amount”, “bankUserId”, “bankName”])
at [Source: [{“bankUserId”:”4005″,”amount”:2800,”bankName”:”邮储银行“,”frontBankCode”:”4005″}]; line: 1, column: 72] (through reference chain: java.util.ArrayList[0]->json.RecvableRecvInfo[“frontBankCode”])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:834)
3 问题解决
1、代码修改
对生成ObjectMapper进行配置
1 |
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); |
2、积累
后续如果有需求要对一个数据表字段的json串进行新增字段,就需要考虑在发布过程中是否也会存在这个问题。
(全文完)