在本文中,我们将带你了解fastjson使用在这篇文章中,我们将为您详细介绍fastjson使用的方方面面,并解答fastjsonenum常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的fa
在本文中,我们将带你了解fastjson 使用在这篇文章中,我们将为您详细介绍fastjson 使用的方方面面,并解答fastjson enum常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的
- fastjson 使用(fastjson enum)
fastjson与内部类小记 - Android 使用fastjson找不到fastjson包问题的解决方法
- com.alibaba.fastjson.support.spring.FastJsonJsonView的实例源码
- FASTJSON 2.0 发布,FASTJSON 项目的重要升级
fastjson 使用(fastjson enum)
原文地址http://jingyan.baidu.com/article/c74d6000672e450f6b595d53.html
阿里的fastjson包对对象进行 json的转化与解析。测试了下效率比net.sf.json和spring mvc自带的转换效率高得多!
常用类型
类型一:JavaBean
类型二:List<JavaBean>
类型三:List<String>
类型四:List<Map<String,Object>>
将上面的四种数据对象转换成json字符串的方法都是一样的
String jsonString = JSON.toJSONString(obj);
1.)将json字符串转化成JavaBean对象
Person person = new Person("1","fastjson",1); //序列化,这里将javabean转化成json字符串 String jsonString = JSON.toJSONString(person); //反序列化,这里将json字符串转化成javabean对象,person =JSON.parSEObject(jsonString,Person.class);
2.)将json字符串转化成List<JavaBean>对象
Person person1 = new Person("1","fastjson1",1); Person person2 = new Person("2","fastjson2",2); List<Person> persons = new ArrayList<Person>(); persons.add(person1); persons.add(person2); //序列化,转换为json字符串 String jsonString = JSON.toJSONString(persons); System.out.println("json字符串:"+jsonString); //反序列化,将json字符串转换为list List<Person> persons2 = JSON.parseArray(jsonString,Person.class);
3.)将json字符串转化成List<String>对象
List<String> list = new ArrayList<String>(); list.add("fastjson1"); list.add("fastjson2"); list.add("fastjson3"); String jsonString = JSON.toJSONString(list); System.out.println("json字符串:"+jsonString); //反序列化 List<String> list2 = JSON.parSEObject(jsonString,new TypeReference<List<String>>(){});
4.)将json字符串转化成List<Map<String,Object>>对象
Map<String,Object> map = new HashMap<String,Object>(); map.put("key1","value1"); map.put("key2","value2"); Map<String,Object> map2 = new HashMap<String,Object>(); map2.put("key1",1); map2.put("key2",2); List<Map<String,Object>> list = new ArrayList<Map<String,Object>>(); list.add(map); list.add(map2); String jsonString = JSON.toJSONString(list); System.out.println("json字符串:"+jsonString); //反序列化 List<Map<String,Object>> list2 = JSON.parSEObject(jsonString,new TypeReference<List<Map<String,Object>>>(){});
5.)日期格式化
Date date=new Date(); //输出毫秒值 System.out.println(JSON.toJSONString(date)); //默认格式为yyyy-MM-dd HH:mm:ss System.out.println(JSON.toJSONString(date,SerializerFeature.WriteDateUseDateFormat)); //根据自定义格式输出日期,这个格式不能反序列化 System.out.println(JSON.toJSONStringWithDateFormat(date,"yyyy-MM-dd",SerializerFeature.WriteDateUseDateFormat));
为了大家学习使用的方便,将测试java项目打包上传到了百度网盘,下载地址
pan.baidu.com/s/1jGskEb0
fastjson与内部类小记
fastjson与内部类小记
问题:
json解析java内部类时,在使用fastjson的以下方法,出现了空指针
public static <T> T parSEObject(String text,Class<T> clazz)
场景:
1.java代码有非static修饰的内部类
2.fastjson版本1.2.7
解决:
1将待转换的model里面的内部类用static修饰.2将内部类拿出来
复现:
过程:
1.跟踪源码
最终报错到JavaBeanDeserializer.java:113所以我们从头跟踪到这里就行.
从parSEObject开始,
图中红色为有问题的地方,其它代码不做研究,这个parse是个解析器,封装了配置信息,时间格式,和parseContext(最终是这个报错,但不是这个问题)
进来之后,红色框里面的是个反序列实现,里面最终返回了一个确定反序列子类,这个方法进去之后,debugger最终我们的数据委托给了JavaBeanDeserializer.
转到JavaBeanDeserializer.createInstance方法里面,来到我们出问题的代码,在这之前,并没有发现哪里有初始化context的操作,因此,可以判断问题不是在这,与空指针无关.现在继续走代码到,文章最初飘红的代码,最后研究下这个代码要做什么(因为代码不长,所以截图不会很多,此处没有详细说明)
这时我们发现,代码走的是else条件,也就是说创建的是有参的构造方法,来初始化.
最终,找到问题所在了.
2.整理问题
我们的内部类没有带参的构造方法,为什么这里会出现初始化有参的构造方法?
3.找关联
既然是Constructor这有问题,那么我们看下这个方法的api
Constructor.newInstance
英文表示太多不爱看,搜索下关键字inner,发现了一个线索,这个意思大概是说内部类不是static声明的,第一个参数应该是封闭实例,而且给了一个参考章节
章节
看了这个章节的内容,表示不懂,到现在为止,只知道"非静态内部类,持有外部类的一个实例",想一下这个和那个有什么关系呢.(其实到这里,google百度可以解决问题了)
4.求人不如求已
记得以前看过内部类的class文件,所以,现在想去看下class文件构造.
javac Tester.java后,一看目录下面生成了两个文件Testter.class和Testter$nest.class,idea自带了反编译,我用eclipse打开查看了这两个class文件,终于发现问题了!!
原来内部类是通过构造方法来设置外部类引用的,这样初始化时,必须要传参数才行(再具体的详情请转@朝花夕拾——Java的synthetic修饰词)
5.验证
去了fastjson,发现有人有过这样的问题,随后google搜索了一番,发现原因是正确的.
以上均为个人观点,欢迎指正.
Android 使用fastjson找不到fastjson包问题的解决方法
JSON解析库有很多,诸如Jackson,Json-lib,org.json,Gson和fastjson等,但是fastjson以其解析速度最快而脱颖而出。详细的测试地址如下:
https://github.com/eishay/jvm-serializers/wiki/Staging-Results
fastjson是国内alibaba公司的wenshao开发的,项目Git地址:
https://github.com/alibaba/fastjson
今天测试了下发现fastjson挺好用,比Android自带的org.json库要好用多了。当然我没有对fastjson的性能进行测试,只是因为Android自带的不太好。
在普通的java项目下,只需要导入fastjson.jar就可以,无需依赖其他包,这一点相比json-lib要好多,json-lib依赖五六个包。但是将fastjson.jar导入Android工程后,在使用时会出现 java.lang.NoClassDefFoundError:can''t find com.alibaba.fastjson.JSON等错误消息。
初步认为是与Android自带的org.json冲突。于是Build Path->Configure Build Path->Order And Export下将fastjson.jar上调至Android xx.jar上(xx为android 版本号)。再运行工程,这个错误不再出现了,奇迹般的没问题了。
然后现在再调整fastjson.jar和Android.jar顺序也不会出现can''t not find com.alibaba.fastjson的错误,不知道为何,继续看。
文章Java虚拟机类加载顺序讲解了java 虚拟机加载class和jar包的顺序。
bootstrap classloader ->extension classloader->system classloader
其中bootstrap引导类加载器;
extension classloader扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的类包;
system classloader系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者 CLASSPATH操作系统属性所指定的JAR类包和类路径.
该文中还有一句话是这么说的,应该能解决我们的疑惑:
“此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必须重新启动JVM才能生效的原因。”
我想应该是Android虚拟机中已经有了fastjson的cache了,所以导致如何更改项目的fastjson.jar和Android.jar顺序都不会有任何反应。我的理解是这样,不知道对不对,欢迎大侠指正。
解释到这里,也解决了我另外一个疑问,就是在Android的工程中新建一个java类,并生成main方法,然后Run->Java Application. 结果会出现如下的错误:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (classFileParser.cpp:3494), pid=5940, tid=5632
# Error: ShouldNotReachHere()
这个问题的产生就是和bootstrap classloard 有关了,文件上右键Run As->Run Configuration选择Java Application下的这个Java类,然后选择右侧的Classpath标签页下有两个目录,分别是Bootstrap Entries 和 User Entries。
Android工程中Bootsrap下默认的是Android Classpath Container,而Java则应该是JRE System Library。所以按照该文Error: ShouldNotReachHere()的解决方法,更改就好了。
com.alibaba.fastjson.support.spring.FastJsonJsonView的实例源码
@Test public void test_jsonp() throws Exception { FastJsonjsonView view = new FastJsonjsonView(); Assert.assertNotNull(view.getFastJsonConfig()); view.setFastJsonConfig(new FastJsonConfig()); view.setExtractValueFromSingleKeyModel(true); view.setdisableCaching(true); MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("callback","queryName"); MockHttpServletResponse response = new MockHttpServletResponse(); Assert.assertEquals(true,view.isExtractValueFromSingleKeyModel()); view.render(Collections.singletonMap("abc","cde中文"),request,response); String contentAsstring = response.getContentAsstring(); int contentLength = response.getContentLength(); Assert.assertEquals(contentLength,contentAsstring.getBytes(view.getFastJsonConfig().getCharset().name()).length); }
@RequestMapping(value = "/getProgress/{fileKey}",method = RequestMethod.GET) public ModelAndView getProgress(@PathVariable("fileKey") String fileKey,Map<String,Object> model) { if (PROCESS_MAP.containsKey(fileKey)) { Tuple2Unit<Integer,Integer> progresstuple = PROCESS_MAP.get(fileKey); model.put("status","processing"); model.put("precent",progresstuple.getP1() * 100 / progresstuple.getP2()); } else { model.put("status","OK"); } return new ModelAndView(new FastJsonjsonView()); }
@Override public void configureViewResolvers(ViewResolverRegistry registry) { FastJsonjsonView fastJsonjsonView = new FastJsonjsonView(); registry.enableContentNegotiation(fastJsonjsonView); }
@SuppressWarnings("deprecation") public void test_0() throws Exception { FastJsonjsonView view = new FastJsonjsonView(); Assert.assertEquals(Charset.forName("UTF-8"),view.getCharset()); view.setCharset(Charset.forName("GBK")); Assert.assertEquals(Charset.forName("GBK"),view.getCharset()); Assert.assertNull(view.getDateFormat()); view.setDateFormat("yyyyMMdd"); Assert.assertNotNull(view.getFeatures()); Assert.assertEquals(1,view.getFeatures().length); view.setSerializerFeature(SerializerFeature.browserCompatible); Assert.assertEquals(1,view.getFeatures().length); Assert.assertEquals(SerializerFeature.browserCompatible,view.getFeatures()[0]); view.setFeatures(SerializerFeature.disableCheckSpecialChar,SerializerFeature.sortField); Assert.assertEquals(2,view.getFeatures().length); Assert.assertEquals(SerializerFeature.disableCheckSpecialChar,view.getFeatures()[0]); Assert.assertEquals(SerializerFeature.sortField,view.getFeatures()[1]); view.setFilters(serializefilter); Assert.assertEquals(1,view.getFilters().length); Assert.assertEquals(serializefilter,view.getFilters()[0]); Map<String,Object> model = new HashMap<String,Object>(); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); view.render(model,response); view.setRenderedAttributes(null); view.setCharset(Charset.forName("UTF-8")); view.render(model,response); view.setUpdateContentLength(true); view.setFeatures(SerializerFeature.browserCompatible); view.render(model,response); view.setCharset(Charset.forName("GBK")); view.render(Collections.singletonMap("abc","cde"),response); view.setdisableCaching(false); view.setUpdateContentLength(false); view.render(model,response); view.setRenderedAttributes(new HashSet<String>(Collections.singletonList("abc"))); view.render(Collections.singletonMap("abc",response); }
public void test_1() throws Exception { FastJsonjsonView view = new FastJsonjsonView(); Assert.assertNotNull(view.getFastJsonConfig()); view.setFastJsonConfig(new FastJsonConfig()); Map<String,Object>(); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); view.render(model,response); view.setRenderedAttributes(null); view.render(model,response); view.setUpdateContentLength(true); view.render(model,response); view.setExtractValueFromSingleKeyModel(true); Assert.assertEquals(true,view.isExtractValueFromSingleKeyModel()); view.setdisableCaching(true); view.render(Collections.singletonMap("abc",response); }
@Test public void test_jsonp_invalidparam() throws Exception { FastJsonjsonView view = new FastJsonjsonView(); Assert.assertNotNull(view.getFastJsonConfig()); view.setFastJsonConfig(new FastJsonConfig()); view.setExtractValueFromSingleKeyModel(true); view.setdisableCaching(true); MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("callback","-methodName"); MockHttpServletResponse response = new MockHttpServletResponse(); Assert.assertEquals(true,view.isExtractValueFromSingleKeyModel()); view.render(Collections.singletonMap("doesn't matter",Collections.singletonMap("abc","cde中文")),response); String contentAsstring = response.getContentAsstring(); Assert.assertTrue(contentAsstring.startsWith("{\"abc\":\"cde中文\"}")); }
FASTJSON 2.0 发布,FASTJSON 项目的重要升级
FASTJSON 2.0 是 FASTJSON 项目的重要升级,目标是为下一个十年提供一个高性能的 JSON 库,同一套 API 支持 JSON/JSONB 两种协议,JSONPath 是一等公民,支持全量解析和部分解析,支持 Java 服务端、客户端 Android、大数据场景。
1. 介绍
- FASJTONS2 代码 https://github.com/alibaba/fastjson2/releases/tag/2.0.1
- JSONB 格式文档 https://github.com/alibaba/fastjson2/wiki/jsonb_format_cn
- FASTJSON 2 性能有了很大提升,具体性能数据看这里 https://github.com/alibaba/fastjson2/wiki/fastjson_benchmark
2. 使用前准备
2.1 Maven依赖
在fastjson 2.0中,groupId和1.x不一样,是com.alibaba.fastjson2
<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.1</version> </dependency>
https://repo1.maven.org/maven2/com/alibaba/fastjson2/fastjson2/
2.2
如果原来使用fastjson 1.2.x版本,可以使用兼容包,兼容包不能保证100%兼容,请仔细测试验证,发现问题请及时反馈。
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.1</version> </dependency>
2.2 常用类和方法
在fastjson 2.0中,package和1.x不一样,是com.alibaba.fastjson2。如果你之前用的是fastjson1,大多数情况直接更包名就即可。
package com.alibaba.fastjson2; class JSON { // 将字符串解析成JSONObject static JSONObject parseObject(String str); // 将字符串解析成JSONArray static JSONArray parseArray(String str); // 将字符串解析成Java对象 static T parseObject(byte[] utf8Bytes, Class<T> objectClass); // 将Java对象输出成字符串 static String toJSONString(Object object); // 将Java对象输出成UT8编码的byte[] static byte[] toJSONBytes(Object object); } class JSONB { // 将jsonb格式的byte[]解析成Java对象 static T parseObject(byte[] jsonbBytes, Class<T> objectClass); // 将Java对象输出成jsonb格式的byte[] static byte[] toBytes(Object object); } class JSONObject { Object get(String key); int getIntValue(String key); Integer getInteger(String key); long getLongValue(String key); Long getLong(String key); T getObject(String key, Class<T> objectClass); // 将JSONObject对象转换为Java对象 T toJavaObject(Class<T> objectClass); } class JSONArray { Object get(int index); int getIntValue(int index); Integer getInteger(int index); long getLongValue(int index); Long getLong(int index); T getObject(int index, Class<T> objectClass); } class JSONPath { // 构造JSONPath static JSONPath of(String path); // 根据path直接解析输入,会部分解析优化,不会全部解析 Object extract(JSONReader jsonReader); // 根据path对对象求值 Object eval(Object rootObject); } class JSONReader { // 构造基于String输入的JSONReader static JSONReader of(String str); // 构造基于ut8编码byte数组输入的JSONReader static JSONReader of(byte[] utf8Bytes); // 构造基于char[]输入的JSONReader static JSONReader of(char[] chars); // 构造基于json格式byte数组输入的JSONReader static JSONReader ofJSONB(byte[] jsonbBytes) }
3. 读取JSON对象
String str = "{\"id\":123}"; JSONObject jsonObject = JSON.parseObject(str); int id = jsonObject.getIntValue("id");
String str = "[\"id\", 123]"; JSONArray jsonArray = JSON.parseArray(str); String name = jsonArray.getString(0); int id = jsonArray.getIntValue(1);
4. 将JavaBean对象生成JSON
4.1 将JavaBean对象生成JSON格式的字符串
class Product { public int id; public String name; } Product product = new Product(); product.id = 1001; product.name = "DataWorks"; JSON.toJSONString(product); // 生成如下的结果 { "id" : 1001, "name" : "DataWorks" } JSON.toJSONString(product, JSONWriter.Feature.BeanToArray); // 生成如下的结果 [123, "DataWorks"]
4.2 将JavaBean对象生成UTF8编码的byte[]
Product product = ...; byte[] utf8JSONBytes = JSON.toJSONBytes(product);
4.3 将JavaBean对象生成JSONB格式的byte[]
Product product = ...; byte[] jsonbBytes = JSONB.toBytes(product); byte[] jsonbBytes = JSONB.toBytes(product, JSONWriter.Feature.BeanToArray);
5. 读取JavaBean
5.1 将字符串读取成JavaBean
String str = "{\"id\":123}"; Product product = JSON.parseObject(str, Product.class);
5.2 将UTF8编码的byte[]读取成JavaBean
byte[] utf8Bytes = "{\"id\":123}".getBytes(StandardCharsets.UTF_8); Product product = JSON.parseObject(utf8Bytes, Product.class);
5.3 将JSONB数据读取成JavaBean
byte[] jsonbBytes = ... Product product = JSONB.parseObject(jsonbBytes, Product.class); Product product = JSONB.parseObject(jsonbBytes, Product.class, JSONReader.Feature.SupportBeanArrayMapping);
6. 使用JSONPath
6.1 使用JSONPath部分读取数据
String str = ...; JSONPath path = JSONPath.of("$.id"); // 缓存起来重复使用能提升性能 JSONReader parser = JSONReader.of(str); Object result = path.extract(parser);
6.2 使用JSONPath读取部分utf8Bytes的数据
byte[] utf8Bytes = ...; JSONPath path = JSONPath.of("$.id"); // 缓存起来重复使用能提升性能 JSONReader parser = JSONReader.of(utf8Bytes); Object result = path.extract(parser);
6.3 使用JSONPath读取部分jsonbBytes的数据
byte[] jsonbBytes = ...; JSONPath path = JSONPath.of("$.id"); // 缓存起来重复使用能提升性能 JSONReader parser = JSONReader.ofJSONB(jsonbBytes); // 注意,这是利用ofJSONB方法 Object result = path.extract(parser);
详情可查看:https://github.com/alibaba/fastjson2/releases
今天关于fastjson 使用和fastjson enum的分享就到这里,希望大家有所收获,若想了解更多关于
本文标签: