大家在使用Json反序列化时,有几个点需要注意一下的,这样可以方便大家以后更好的使用json,那么下面我们就给大家分享一些json反序列化注意的问题。大家可以参考以下内容。
1、内部类问题
反序列化一个类的内部类时,可能会获取意想不到的结果,实例如下:
// 测试用例package com.mogu.hui.study.json; import java.util.List; /** * 用于测试json序列化 * Created by yihui on 16/4/22. */ public class JsonHello { private String name; private Hello hello; public JsonHello() {} public String getName() { return name; } public void setName(String name) { this.name = name; } public Hello getHello() { return hello; } public void setHello(String hello, Listuser) { Hello h = new Hello(); h.setHello(hello); h.setUser(user); this.hello = h; } @Override public String toString() { return "JsonHello{" + "name='" + name + '\'' + ", hello=" + hello + '}'; } private class Hello { String hello; Listuser; public Hello() {} public String getHello() { return hello; } public void setHello(String hello) { this.hello = hello; } public ListgetUser() { return user; } public void setUser(Listuser) { this.user = user; } @Override public String toString() { return "Hello{" + "hello='" + hello + '\'' + ", user=" + user + '}'; } } }
测试文件容下:
package com.mogu.hui.study.json; import com.alibaba.fastjson.JSON; import org.junit.Test; import org.slf4j.LoggerFactory; import org.slf4j.Logger; import java.util.Arrays; /** * Created by yihui on 16/4/22. */ public class JsonTest { private static Logger logger = LoggerFactory.getLogger(JsonTest.class); @Test public void innerClassTest() { try { JsonHello jsonHello = new JsonHello(); jsonHello.setName("hello"); jsonHello.setHello("innerHello", Arrays.asList("user1", "user2")); String str = JSON.toJSONString(jsonHello); logger.info("Str: {}", str); Object obj = JSON.parseObject(str, JsonHello.class); logger.info("Obj: {}", obj); } catch (Exception e) { logger.info("error: {}", e); } } }
输出结果:
17:20:08.863 [main] INFO com.mogu.hui.study.json.JsonTest - Str: {"hello":{"hello":"innerHello","user":["user1","user2"]},"name":"hello"}17:21:44.425 [main] INFO com.mogu.hui.study.json.JsonTest - Obj: JsonHello{name='hello', hello=null}
从上面的输出可以看出,反序列化对象的时候,出现诡异的事情,JsonHello对象的hello元素变成了 null
那么是如何产生这个问题的呢?
其实也简单,因为内部类,json反序列化的时候,无法得到该类,"hello":{"hello":"innerHello","user":["user1","user2"]} 这个串没法愉快的转换为 Hello 对象
这种问题如何避免?
不要反序列化匿名类,内部类!
2、 枚举反序列化
当序列化的对象中,包含枚举时,反序列化可能得不到你预期的结果,枚举对象变成了一个String对象, 其实和上面的问题一样,需要
package com.mogujie.service.rate.base; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import org.junit.Test; import java.util.ArrayList; import java.util.List; /** * Created by yihui on 16/10/31. */ public class JsonTest { public enum MyDay { YESDAY("SUNDAY"), TODAY("MONDAY"), TOMORROW("TUESDAY"); private String today; MyDay(String today) { this.today = today; } public String getToday() { return today; } @Override public String toString() { return "MyDay{" + "today='" + today + '\'' + '}'; } } class TTT { MyDay myDay; public TTT() {} public TTT(MyDay myDay) { this.myDay = myDay; } @Override public String toString() { return "TTT{" + "myDay=" + myDay + '}'; } } private MyDay getDay() { return MyDay.TODAY; } @Test public void testJson() { String str = JSON.toJSONString(getDay()); System.out.println(str); // 这样反序列化ok MyDay myDay = JSON.parseObject(str, MyDay.class); System.out.println(myDay); ListmyDayList = new ArrayList < > (); myDayList.add(MyDay.TODAY); myDayList.add(MyDay.TOMORROW); String str2 = JSON.toJSONString(myDayList); System.out.println(str2); // 反序列化失败, 和模板类的问题一样 try { Listout = JSON.parseObject(str2, List.class); for (MyDay myDay1: out) { System.out.println(myDay1); } } catch (Exception e) { e.printStackTrace(); } // 采用这种方式,反序列化ok TypeReference < list > typeReference = new TypeReference < list > () {}; try { Listout = JSON.parseObject(str2, typeReference); for (MyDay myDay1: out) { System.out.println(myDay1); } } catch (Exception e) { e.printStackTrace(); } System.out.println("------------"); TTT tt = new TTT(MyDay.TODAY); String str3 = JSON.toJSONString(tt); System.out.println(str3); // 直接反序列化异常 try { TTT recover = JSON.parseObject(str3, TTT.class); System.out.println(recover); } catch (Exception e) { e.printStackTrace(); } } }
输出内容
"TODAY" MyDay { today = 'MONDAY' } ["TODAY", "TOMORROW"] java.lang.ClassCastException: java.lang.String cannot be cast to com.mogujie.service.rate.base.JsonTest$MyDay at com.mogujie.service.rate.base.JsonTest.testJson(JsonTest.java: 79) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43) at java.lang.reflect.Method.invoke(Method.java: 606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java: 47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java: 12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java: 44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java: 17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java: 271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java: 70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java: 50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java: 238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java: 63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java: 236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java: 53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java: 229) at org.junit.runners.ParentRunner.run(ParentRunner.java: 309) at org.junit.runner.JUnitCore.run(JUnitCore.java: 160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java: 69) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java: 234) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java: 74) MyDay { today = 'MONDAY' } MyDay { today = 'TUESDAY' }-- -- -- -- -- -- {} com.alibaba.fastjson.JSONException: create instance error, class com.mogujie.service.rate.base.JsonTest$TTT at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java: 116) at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java: 356) at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java: 135) at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java: 551) at com.alibaba.fastjson.JSON.parseObject(JSON.java: 251) at com.alibaba.fastjson.JSON.parseObject(JSON.java: 227) at com.alibaba.fastjson.JSON.parseObject(JSON.java: 186) at com.alibaba.fastjson.JSON.parseObject(JSON.java: 304) at com.mogujie.service.rate.base.JsonTest.testJson(JsonTest.java: 108) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43) at java.lang.reflect.Method.invoke(Method.java: 606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java: 47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java: 12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java: 44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java: 17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java: 271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java: 70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java: 50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java: 238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java: 63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java: 236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java: 53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java: 229) at org.junit.runners.ParentRunner.run(ParentRunner.java: 309) at org.junit.runner.JUnitCore.run(JUnitCore.java: 160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java: 69) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java: 234) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java: 74) Caused by: java.lang.NullPointerException at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java: 113) ...29 moreDisconnected from the target VM, address: '127.0.0.1:52140', transport: 'socket' Process finished with exit code 0
这些就是大家在使用json反序列化时需要注意的,大家要重视起来。最后大家如果想要了解更多json工具教程知识,敬请关注奇Q工具网。
推荐阅读:
springmvc工作流程是什么?springmvc组件作用有哪些?