- 浏览: 3533 次
文章分类
最新评论
基于org.json的快速构建和解析json文本扩展工具
之前做过一个项目需要使用json来传输数据,我用的是org.json,但是其构造和解析方法过于繁琐,想到之前解析xml时用的simpleXml可以通过注解的方式构造和解析xml文本,
我就参考simpleXml,利用java的反射机制做了一个基于org.json的工具包,这个工具同样可以通过注解来构造json。
首先是一个接口,这个接口是个标记,表名一个类可以使用这个工具转换json
package dikaros.json.annotation; /** * 动态转换标记<br> * 表示该实例类可以被动态转换成json信息<br> * @author Dikaros * */ public interface Jsonable { }
package dikaros.json.annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * JsonParam 标准类型注解用在类的基本属性前<br> * 在生成json文本后为键值对的key<br> * @author Dikaros * */ //注解会在class字节码文件中存在,在运行时可以通过反射获取到 @Retention(RetentionPolicy.RUNTIME) public @interface JsonParam { /** * json文本 键 * @return */ public String name() default ""; }
注解JsonListParam
package dikaros.json.annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * JsonParam 标准类型注解用在类的基本属性前<br> * 在生成json文本后为键值对的key<br> * className表示数组类型或集合的泛型如<code>String.class</code><br> * 枚举类型TYPE表示数组类型ARRAY表示数组,例如int[], LIST表示集合,例如java.util.List<br> * * @author Dikaros * @see TYPE * */ // 注解会在class字节码文件中存在,在运行时可以通过反射获取到 @Retention(RetentionPolicy.RUNTIME) public @interface JsonListParam { public String name() default ""; /** * 数组类型或集合泛型 * @return */ public Class contentClassName(); /** * 设置是集合还是数组 * @return <code>TYPE.ARRAY</code>或<code>TYPE.LIST</code> * @see TYPE */ public TYPE classType() default TYPE.LIST; /** * 多数据类型<br> * ARRAY表示数组,例如int[]<br> * LIST表示集合,例如java.util.List<br> * 默认为LIST * * @author Dikaros * */ public enum TYPE { ARRAY, LIST }; }
然后就是主要的工具类了,由于这个类是基于org,json的,所以相关的org.json大家可以从其他地方下载,另外本文还附带了一个jar包,需要的可以下载
package dikaros.json; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import dikaros.json.annotation.JsonListParam; import dikaros.json.annotation.JsonParam; import dikaros.json.annotation.Jsonable; import dikaros.json.annotation.JsonListParam.TYPE; import dikaros.org.json.JSONArray; import dikaros.org.json.JSONException; import dikaros.org.json.JSONObject; import dikaros.org.json.JSONStringer; /** * org.json扩展<br> * 将类构造成简单的json文本<br> * 注意:构造的类需要实现Jsonable接口,并且是标准的JavaBean<br> * 原理:通过反射机制获取需要转换成json对象的注解,根据注解的内容生成key<br> * 由于注解是添加在变量上的,如果类拥有标准get和set方法,则通过反射获取<br> * 并执行这些方法即可当作value<br> * 建议:将一些类型改变为基本类型,如java.util.Date用long来表示 * * @author Dikaros * @see Jsonable * @see JsonParam * @see JsonListParam */ public class JsonExtendedUtil { /** * 构造一个对象的json * * @param object * 需要转换成json的对象,需要实现Jsonable接口 * @return json文本 * @throws Exception */ public static String generateJson(Object object) throws Exception { JSONStringer stringer = new JSONStringer(); stringer.array(); generateObjectMessage(object, stringer); stringer.endArray(); return stringer.toString(); } /** * 构造json<br> * 原理:通过反射机制获取注解并将其作为key,再调用field的get方法即可得到value * * @param object * 需要转换成json的对象,需要实现Jsonable接口 * @param stringer * org.json的json构造器 * @throws Exception */ private static void generateObjectMessage(Object object, JSONStringer stringer) throws Exception { // 如果object没有实现Jsonable接口,则抛出异常 if (!(object instanceof Jsonable)) { throw new Exception("不支持的类型格式,是否忘记了实现JsonAble接口"); } // 开始构造json对象 stringer.object(); Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(JsonParam.class)) { JsonParam jsonParam = field.getAnnotation(JsonParam.class); // json键 stringer.key(jsonParam.name()); Method method = getFieldMethod(clazz, field); Object value = method.invoke(object, new Object[] {}); // json值 stringer.value(value); } else if (field.isAnnotationPresent(JsonListParam.class)) { // System.out.println("list"); JsonListParam jsonListParam = field .getAnnotation(JsonListParam.class); // 字段名称,根据字段名称获取其对应的get方法 Method method = getFieldMethod(clazz, field); Object value = method.invoke(object, new Object[] {}); if (value == null) { continue; } if (jsonListParam.classType() == TYPE.ARRAY) { Array.getLength(value); // 调用get方法 stringer.key(jsonListParam.name()); // 集合的键 stringer.array(); // 集合字段 for (int i = 0; i < Array.getLength(value); i++) { Object listItem = Array.get(value, i); // 如果集合是JsonAble的实例则调用此函数 if ((listItem instanceof Jsonable)) { generateObjectMessage(listItem, stringer); } // 如果集合不是JsonAble的实例 else if (isBaseType(listItem)) { stringer.value(listItem); } else { throw new Exception("集合元素类型不支持,请将集合内元素实现JsonAble接口"); } } // 集合结束 stringer.endArray(); } else if (jsonListParam.classType() == TYPE.LIST) { // 调用get方法 stringer.key(jsonListParam.name()); // 集合的键 stringer.array(); // 集合字段 List list = (List) value; for (Object listItem : list) { // 如果集合是JsonAble的实例则调用此函数 if ((listItem instanceof Jsonable)) { generateObjectMessage(listItem, stringer); } // 如果集合不是JsonAble的实例 else if (isBaseType(listItem)) { stringer.value(listItem); } else { throw new Exception("集合元素类型不支持,请将集合内元素实现JsonAble接口"); } } // 集合结束 stringer.endArray(); } } } // json对象结束 stringer.endObject(); } /** * 判断对象是否是基本类型 * * @return true是,false 不是 */ private static boolean isBaseType(Object obj) { boolean result = false; if ((obj instanceof Integer) || (obj instanceof Byte) || (obj instanceof Double) || (obj instanceof Boolean) || (obj instanceof String) || (obj instanceof Short) || (obj instanceof Long) || (obj instanceof Character) || (obj instanceof Float)) { result = true; } return result; } /** * 获取JavaBean字段的get方法 */ private static Method getFieldMethod(Class clazz, Field field) throws Exception { String fieldName = field.getName(); fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method method = null; try { if (field.getType() == Boolean.class) { method = clazz.getMethod("is" + fieldName, null); } else { method = clazz.getMethod("get" + fieldName, null); } } catch (NoSuchMethodException e) { throw new Exception("不是标准的JavaBean,注意JavaBean的格式"); } return method; } /** * 获取JavaBean字段的set方法 */ @SuppressWarnings("unchecked") private static Method setFieldMethod(Class clazz, Field field) throws Exception { String fieldName = field.getName(); fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method method = null; try { // System.out.println("set---" + fieldName); method = clazz.getMethod("set" + fieldName, new Class[] { field.getType() }); } catch (NoSuchMethodException e) { throw new Exception("不是标准的JavaBean,注意JavaBean的格式"); } return method; } public static Object compileJson(Class clazz, String jsonFile) throws Exception { JSONArray array = new JSONArray(jsonFile); Object object = null; if (array.length() > 0) { JSONObject jsonObject = array.getJSONObject(0); object = clazz.newInstance(); getObjectFromJsonFile(object, jsonObject.toString()); } return object; } /** * 解析Json<br> * 原理:传入Object获取其类型,通过其类型的注解调用属性的set方法更改Object的值<br> * 注意:该方法的传入json是一个JSONObject型的 * * @param jsonable * 待转换的类 * @param jsonFile * 需要解析的jsonFile * @throws Exception */ private static void getObjectFromJsonFile(Object jsonable, String jsonFile) throws Exception { if (!(jsonable instanceof Jsonable)) { throw new Exception("不支持的类型格式,是否忘记了实现JsonAble接口"); } // 获取class Class clazz = jsonable.getClass(); JSONObject obj = new JSONObject(jsonFile); // 获取类所有的属性 Field[] fields = clazz.getDeclaredFields(); // 遍历所有的属性 for (Field field : fields) { /* * 如果属性中存在JsonParam的注解 从JsonFile中获取内容 通过反射机制调用set方法更新属性 */ if (field.isAnnotationPresent(JsonParam.class)) { JsonParam jsonParam = field.getAnnotation(JsonParam.class); String keyName = jsonParam.name(); Object value = obj.get(keyName); Method method = setFieldMethod(clazz, field); // 调用set方法更新属性 method.invoke(jsonable, new Object[] { value }); } /* * 如果属性中存在JsonListParam的注解 从JsonFile中获取内容 判断多值类型是集合还是数组 * 根据类型采用不同的方法更新属性 */ else if (field.isAnnotationPresent(JsonListParam.class)) { JsonListParam jsonListParam = field .getAnnotation(JsonListParam.class); // 获取键 String keyName = jsonListParam.name(); JSONArray jArray = null; /* * 判断有没有这样的keyName 如果没有,跳过进行下一次循环 */ try { jArray = obj.getJSONArray(keyName); } catch (Exception e) { continue; } if (!(field.getType().equals(List.class)) && !field.getType().isArray()) { throw new Exception("类型错误,类型不是List的实例"); } Method method = setFieldMethod(clazz, field); TYPE classType = jsonListParam.classType(); /* * 如果是集合 构建集合 递归调用此方法进行设置 */ if (classType == TYPE.LIST) { List list = new ArrayList<>(); for (int i = 0; i < jArray.length(); i++) { JSONObject item = jArray.getJSONObject(i); Class itemClass = jsonListParam.contentClassName(); Object itemObject = itemClass.newInstance(); if (itemObject instanceof Jsonable) { getObjectFromJsonFile(itemObject, item.toString()); list.add(itemObject); } else if (isBaseType(itemObject)) { list.add(jArray.get(i)); } } method.invoke(jsonable, new Object[] { list }); } /* * 如果是数组 根据JSONArray大小构建数组 递归调用此方法进行设置 */ else if (classType == TYPE.ARRAY) { // Object[] items = new Object[jArray.length()]; Object items = Array.newInstance( jsonListParam.contentClassName(), jArray.length()); for (int i = 0; i < jArray.length(); i++) { Class itemClass = jsonListParam.contentClassName(); Object itemObject = itemClass.newInstance(); if (itemObject instanceof Jsonable) { JSONObject item = jArray.getJSONObject(i); getObjectFromJsonFile(itemObject, item.toString()); // items[i] = itemObject; Array.set(items, i, itemObject); } else if (isBaseType(itemObject)) { Array.set(items, i, jArray.get(i)); } } System.out.println("method--->" + method.getName() + ":" + method.getParameterTypes()[0]); method.invoke(jsonable, new Object[] { items }); } } } } /** * 获取long值 * * @param jsonFile * @param param * @return */ public static long getLongParam(String jsonFile, String param) { long result = 0; JSONObject obj; JSONArray array; try { array = new JSONArray(jsonFile); if (array.length() > 0) { obj = array.getJSONObject(0); result = obj.getLong(param); } } catch (JSONException e) { e.printStackTrace(); } return result; } /** * 获取boolean值 * * @param jsonFile * @param param * @return */ public static boolean getBooleanParam(String jsonFile, String param) { boolean result = false; JSONObject obj; JSONArray array; try { array = new JSONArray(jsonFile); if (array.length() > 0) { obj = array.getJSONObject(0); result = obj.getBoolean(param); } } catch (JSONException e) { e.printStackTrace(); } return result; } /** * 获取指定字段的内容 * * @param jsonFile * @param param * @return */ public static String getParam(String jsonFile, String param) { String result = null; JSONObject obj; JSONArray array; try { array = new JSONArray(jsonFile); if (array.length() > 0) { obj = array.getJSONObject(0); result = obj.getString(param); } } catch (JSONException e) { e.printStackTrace(); } return result; } /** * 从json文件中获取整型值 * * @param jsonFile * @param param * @return */ public static int getIntParam(String jsonFile, String param) { int result = -1; JSONObject obj; JSONArray array; try { array = new JSONArray(jsonFile); if (array.length() > 0) { obj = array.getJSONObject(0); result = obj.getInt(param); } } catch (JSONException e) { e.printStackTrace(); } return result; } /** * 构建 传输信息 * * @param map * @return */ public static String constructMapJson(HashMap map) { Set set = map.keySet(); JSONStringer jsonStringer = new JSONStringer(); try { jsonStringer.array(); jsonStringer.object(); for (Iterator iterator = set.iterator(); iterator.hasNext();) { String key = (String) iterator.next(); jsonStringer.key(key); jsonStringer.value(map.get(key)); } jsonStringer.endObject(); jsonStringer.endArray(); } catch (JSONException e) { e.printStackTrace(); } return jsonStringer.toString(); } }
下面有一个实例,这个实例演示怎么使用这个工具
假定有一个类Person,注意,由于利用的是java的反射机制,所以这个类一定要是标准的JavaBean,被注解的属性必须有getter和setter方法。
package dikaros.example; import java.util.Arrays; import java.util.List; import dikaros.json.annotation.JsonListParam; import dikaros.json.annotation.JsonParam; import dikaros.json.annotation.Jsonable; import dikaros.json.annotation.JsonListParam.TYPE; /** * 示例对象 * @author Dikaros * */ public class Person implements Jsonable{ public Person(String name, String gender, int age, String cityName) { this.name = name; this.gender = gender; this.age = age; this.cityName = cityName; } public Person() { } @JsonParam(name="name") String name; @JsonParam(name="gender") String gender; @JsonParam(name="age") int age; @JsonParam(name="cityName") String cityName; @JsonListParam(name="friends",contentClassName=Person.class,classType = TYPE.LIST) List<Person> friend; @JsonListParam(name="phones",contentClassName=String.class,classType = TYPE.ARRAY) String [] phones; /** * @return name */ public String getName() { return name; } /** * @param name 要设置的 name */ public void setName(String name) { this.name = name; } /** * @return gender */ public String getGender() { return gender; } /** * @param gender 要设置的 gender */ public void setGender(String gender) { this.gender = gender; } /** * @return cityName */ public String getCityName() { return cityName; } /** * @param cityName 要设置的 cityName */ public void setCityName(String cityName) { this.cityName = cityName; } /** * @return age */ public int getAge() { return age; } /** * @param age 要设置的 age */ public void setAge(int age) { this.age = age; } /** * @return friend */ public List<Person> getFriend() { return friend; } /** * @param friend 要设置的 friend */ public void setFriend(List<Person> friend) { this.friend = friend; } /* (非 Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "Person [name=" + name + ", gender=" + gender + ", age=" + age + ", cityName=" + cityName + ", friend=" + friend + ", phones=" + Arrays.toString(phones) + "]"; } /** * @return phones */ public String[] getPhones() { return phones; } /** * @param phones 要设置的 phones */ public void setPhones(String[] phones) { this.phones = phones; } }
下面是调用
package dikaros.example; import java.util.ArrayList; import dikaros.json.JsonExtendedUtil; public class Example { public static void main(String[] args) throws Exception { Person person = new Person("老王", "男", 20, "长沙"); String[] phones ={"13000000000","14000000000"}; person.setPhones(phones); ArrayList<Person> friends = new ArrayList<>(); friends.add(new Person("A妹子", "女", 19, "江西")); friends.add(new Person("B妹子", "女", 20, "湖北")); person.setFriend(friends); String jsonFile = JsonExtendedUtil.generateJson(person); System.out.println(jsonFile); Person person2 = (Person) JsonExtendedUtil.compileJson(Person.class, jsonFile); System.out.println(person2); } }
输出结果
[{"name":"老王","gender":"男","age":20,"cityName":"长沙","friends":[{"name":"A妹纸","gender":"女","age":19,"cityName":"江西"},{"name":"B妹纸","gender":"女","age":20,"cityName":"湖北"}],"phones":["13000000000","14000000000"]}] Person [name=老王, gender=男, age=20, cityName=长沙, friend=[Person [name=A妹纸, gender=女, age=19, cityName=江西, friend=null, phones=null], Person [name=B妹纸, gender=女, age=20, cityName=湖北, friend=null, phones=null]], phones=[13000000000,14000000000]]
我这里有整合了org.json的工具包,需要的可以下载,顺便换点积分下载工具
相关推荐
6. **JSONTokener**:用于分隔和解析JSON文本,是JSONParser的基础。它逐字符或逐行地读取输入,构建JSON结构。 除了以上核心类,org.json库还提供了JSONPath支持,类似于XPath对于XML的查询功能,可以方便地从复杂...
"net.sf.json"库提供了多种方法,如将Java对象转换为JSON字符串,或者将JSON文本解析为Java对象,这对于构建需要处理JSON数据的Java应用非常有用。 标签"java"表明这个库是专为Java平台设计的,这意味着它可以在...
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它通常用于存储和传输结构化数据,如戏剧的角色、场景、对话等。 - 分析这样的数据可以为文本挖掘、...
为了实现这一目标,你可以创建一个函数,接收JSON字符串作为输入,将其解析为对象,然后构建对应的XML树。同样,也可以创建一个反向的函数,将XML文档解析为对象,再序列化为JSON字符串。这两个函数应该能够处理...
然后,可以使用库提供的API来加载和解析JSON文件,创建并管理GUI组件。这些组件可能包括按钮、文本框、列表视图、滚动条等各种常见的UI元素。此外,CocoGUI可能还支持自定义组件,允许开发者根据需求扩展其功能。 ...
它以文本形式存储和传输数据,易于人阅读和编写,同时也易于机器解析和生成。JSONjar包是将JSON相关的类库打包成的Java Archive(JAR)文件,方便在Java项目中使用。源码则提供了这些类库的原始代码,使得开发者可以...
此库可能包含解析和序列化JSON本地化文件的功能,以及在运行时动态加载和访问这些资源的方法。它可能是通过NuGet包管理器进行安装的,这使得在项目中添加和更新这个库变得非常便捷。"建立状态"可能指的是持续集成或...
1. **JSON解析**:工具首先需要能够读取和解析JSON字符串。在解析过程中,工具会遵循JSON的语法规则,识别对象(key-value对)、数组、数值、字符串、布尔值和null等基本类型。 2. **数据结构构建**:解析后的数据...
通过这个库,程序员可以将C结构体转换为JSON文本,或者从JSON文本中解析出C结构体,实现数据的序列化和反序列化。 `json-c-0.3`目录下通常包含以下内容: 1. 源代码文件:如`.c`和`.h`文件,这些是实现JSON-C功能...
4. **JSON解析与生成**:库提供API来解析JSON文本,创建JSON对象和数组,并生成对应的JSON字符串。例如,`JSONObject`和`JSONArray`类是两个常用的类,分别代表JSON对象和数组。 5. **JSON路径支持**:一些JSON库还...
XML(eXtensible Markup Language)和JSON(JavaScript Object Notation)是两种广泛使用的数据交换格式,它们在Web服务和应用程序...通过理解XML和JSON的差异以及SAX解析的工作原理,我们可以构建出高效的转换工具。
JSON易于人阅读和编写,同时也易于机器解析和生成。在Web服务中,JSON作为数据交换的格式广泛应用,它被用来替代XML,因为其更加简洁、易于处理。 本文将详细介绍C#中如何生成JSON字符串,并结合提供的"Json字符串...
JSON是一种文本格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的一个子集,但并不依赖JavaScript,而是独立的语言中立标准。JavaBean是Java编程中的一个概念,代表具有特定规则的类,通常用来...
虽然JSON是标准的Web格式,但在这里以纯文本形式保存,便于查看和处理,尤其是在没有JSON解析工具的情况下。 标签“Json”、“xls”和“解析”表明了工具的核心功能。在实际应用中,这样的工具可以用于自动化数据...
4. **JSONParser**: `JSONParser`可能包含在`org.json`包中,用于解析JSON文本,将其转化为对应的Java对象。 5. **JSONException**: 当JSON操作过程中出现错误时,会抛出`JSONException`。这可能是由于语法错误、...
这种库通常包含一系列的类和方法,帮助开发者将Java对象转换为JSON字符串,或者将JSON文本解析为Java对象。常见的Java JSON库有Gson、Jackson、org.json和json-simple等,但具体是哪个库,需要查看jar文件的详细内容...
当涉及到**JavaScript**时,我们可以用它来处理JSON数据,比如解析JSON字符串成JavaScript对象,然后通过对象查找、操作或渲染emoji。例如: ```javascript let emojiData = JSON.parse(jsonStr); let firstEmoji =...
在处理JSON时,尤其是在生成或解析JSON字符串时,这类工具方法可能非常有用。 4. `json-lib-2.4-jdk15.jar`:这是一个JSON库,专门用于Java平台,提供了一系列的JSON处理功能,包括将Java对象转换为JSON字符串,...
1. 解析JSON:将JSON字符串转换为数据结构,如JavaScript对象或Python字典。 2. 构建XML:根据JSON的结构创建XML元素和属性。 3. 生成XML:将构建的XML树序列化为字符串。 在编程中,有许多库可以帮助实现这些转换...
Java提供了内置的`org.json`库,或第三方的Gson、Jackson等库,它们提供了方便的方法来将JSON文本转换为Java对象。例如,使用Gson库,我们可以创建一个`Gson`实例,调用`fromJson()`方法将JSON字符串转化为预定义的...