Android学习笔记之Json的使用....
PS:当你的能力还驾驭不了你的目标时,那你需要沉下心来历练...
学习内容:
1.Json的使用...
2.Json信息过滤...
3.从网络上获取Json数据...
4.解析Json数据获取各个属性...
使用Json首先需要下载官方提供的一些jar文件...引用内部提供好的接口...才能够实现Json数据的获取....一共需要六个jar包...我已经进行了上传...大家可以直接下载...
jar下载地址:https://files.cnblogs.com/files/RGogoing/json.rar
下载好了这些jar之后,直接导入就行了...接下来就说真正的内容了...
1.Json的使用...
i.什么是Json...
其实Json和XML文件都一样...它是一种轻量级的数据交换格式。它基于ECMAScript的一个子集...JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。(来自百度)..
但是现在使用XML来完成数据交互并不是非常的多,但是并不意味着Json取代了XML,XML是非常强大的,有很多的事情都是需要使用到XML的...Json只是在数据交互上比XML更有优势而已,使用的更加的广泛,当然数据交互用XML也是完全没有任何问题的....只是Json在这方面的优势要强于XML...至于二者的优缺点我就不提了,百度上有很多关于二者的对比...
ii.Json的数据格式...
Json的数据格式才是我们关心的东西...
第一种:非常简单的一种数据格式...类似于Java里的键值对...
{ "姓名":"Darker", "年龄":20 }
第二种:其实都差不多...这种就类似于数组的格式...好比一个List中保存着HashMap...
{ "学生": [ {"姓名":"Darker","年龄":20}, {"姓名":"ClearLove","年龄":22} ] }
iii.如何在Java应用程序中生成一个Json数据呢?
其实也是非常的简单的...这里需要使用到JSONObject这个类来生成...JSONObject使用JavaBean或者是Map来生成Json数据...
何为Java Bean
JavaBean到底是个什么玩意...其实这个概念很多人都知道,但是不知道Java Bean到底是个什么东西...其实Java Bean是一种惯用模式或规定...这些规定包括getXXX, setXXX, isXXX, addXXXListener等等...遵守这些规定的类可以被用于若干工具和库...还是很抽象..举个例子来理解吧....
这个类用来实现一个链表...这里定义了一个size属性,用来说明链表的大小....
public final class JavaIntList { static class Node { public Node next; public int value; } public Node head; public int size; } JavaIntList myList = new JavaIntList(); System.out.println(myList.size);//调用方法..获取链表的长度...
然后这个类就被发布了..发布成了一个java.jar文件...成为了一个开发需要用的类库...但是某一天我们为了节省内存,我们通过修改java.jar文件用另一种方式获取size...方式如下...然后发布成了java_1.jar
public final class JavaIntList { static final class Node { public Node next; public int value; } public Node head; public int getSize() { Node n = head; int i = 0; while (n != null) { n = n.next; i++; } return i; } }
这样改的结果可想而知,凡是在java.jar开发的应用程序,在升级java_1.jar之后全部都无法正常使用,因为java_1.jar已经看不到size这个属性值了...这就导致了没有向后进行兼容..所以在设计标准库的时候决不允许public int size 这样的代码出现...只能是下面这种方式...以至于在以后修改标准库的时候具备向后兼容...这种惯用手法和规定就被称为Java Bean..
private int size; public int getSize() { return size; }
其实这就是个Java Bean...所有的属性的定义,赋值,获取...等等都只能用这种规定的方式...这就是Java Bean...
package json; public class User { private String username; private String userpassword; private String userid; public String getuserid(){ return userid; } public String getusername(){ return username; } public String getuserpassword(){ return userpassword; } public void setuserid(String userid){ this.userid=userid; } public void setusername(String name){ this.username=name; } public void setuserpassword(String password){ this.userpassword=password; } }
介绍完了这些...就可以正式的说一下如何使用JSONObject生成Json数据了...
第一种使用Java Bean生成Json数据...
Java Bean :User类....
package json; public class User { private String username; private String userpassword; private String userid; public String getuserid(){ return userid; } public String getusername(){ return username; } public String getuserpassword(){ return userpassword; } public void setuserid(String userid){ this.userid=userid; } public void setusername(String name){ this.username=name; } public void setuserpassword(String password){ this.userpassword=password; } }
主函数:通过下面的方式就实现了Json数据的生成,以及获取的过程....
package json; import net.sf.json.JSONObject; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub User user=new User(); /* * 通过JavaBean构建一个Json数据... * */ user.setusername("Darker"); user.setuserpassword("49681888"); user.setuserid("1"); JSONObject json=JSONObject.fromObject(user); System.out.println(json.toString()); } }
第二种JSONObject通过Map来生成Json数据信息....并获取数据信息...
package json; import java.util.HashMap; import net.sf.json.JSONObject; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub /* * 通过map生成Json数据... * */ HashMap<Object, Object>usermap=new HashMap<Object, Object>(); usermap.put("username", "Darker"); usermap.put("userpassword", "49681888"); usermap.put("userid","1"); JSONObject json_1=JSONObject.fromObject(usermap); System.out.println(json_1.toString()); } }
这里我们可以看到,获取到Json数据的方式是使用JSONObject.fromObject()方法实现的...不得不说看了源码部分真是觉得在数据的获取上以及对象的初始化上做的非常的好...Json数据的类型只能是数字,字符串,逻辑值...如果不满足这些情况,返回一个空对象...源码如下...
if (JSONUtils.isNumber(object) || JSONUtils.isBoolean(object) || JSONUtils.isString(object)){ return new JSONObject(); }
public JSONObject(){ this.properties = new ListOrderedMap(); } public JSONObject(boolean isNull){//用的很少... this(); this.nullObject = isNull; }
这里对象的初始化使用了ListOrderMap,ListOrderMap是List和Map优势结合的一种扩展...因为List保存的值是有序的,Map在查询数据的时候是非常高效的..因此结合了这二者的优点存储数据既是有序的,并且在查询的过程也是高效的...ListOrderMap就具备这个特点...扩展了两个集合类...
public static JSONObject fromObject(Object object){ return fromObject(object, new JsonConfig()); }
最后调用fromObject方法...通过JsonConfig的默认配置获取所有的数据信息....
2.Json信息过滤...
我们可以看到,上面通过调用fromObject()方法,使用默认的JsonConfig配置属性,可以获取所有的Json数据信息...但是如果我们想要获取的信息只是Json数据的某一些部分呢?那么我们就需要使用到过滤的方式,把不想要的数据信息直接过滤掉,就可以获取到指定的数据信息了...过滤信息有三种方式...在这里进行介绍...
i.使用一个类实现JsonString接口...覆盖内部的toJsonString()方法...
User类:
实现了userid属性的过滤....
package json; import net.sf.json.JSONString; public class User implements JSONString{ private String username; private String userpassword; private String userid; /** * 实现过滤的方式...重写toJSONString()接口... * * */ @Override public String toJSONString() { // TODO Auto-generated method stub return "{\"username\":\"" + username + "\",\"userpassword\":\"" + userpassword + "\"}"; } public String getuserid(){ return userid; } public String getusername(){ return username; } public String getuserpassword(){ return userpassword; } public void setuserid(String userid){ this.userid=userid; } public void setusername(String name){ this.username=name; } public void setuserpassword(String password){ this.userpassword=password; } }
主函数:
package json; import net.sf.json.JSONObject; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub User user=new User(); user.setusername("Darker"); user.setuserpassword("49681888"); user.setuserid("1"); JSONObject json=JSONObject.fromObject(user); System.out.println(json.toString()); } }
ii.配置JSONConfig...通过使用JSONConfig.setExclude()方法设置过滤的属性...这里就不再贴出User类了...
这里我们可以看到,通过使用setExclude()方法...过滤掉了userid属性...
package json; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub User user=new User(); user.setusername("Darker"); user.setuserpassword("49681888"); user.setuserid("1"); /** * 实现属性过滤的第二种方式...配置JSONConfig.... * */ JsonConfig config=new JsonConfig(); /* * 设置不包含的属性... * */ config.setExcludes(new String[]{"userid"}); JSONObject object=JSONObject.fromObject(user, config); System.out.println(object.toString()); } }
iii.使用PropertyFilter实现属性过滤....
package json; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; import net.sf.json.util.PropertyFilter; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub User user=new User(); user.setusername("Darker"); user.setuserpassword("49681888"); user.setuserid("1"); /** * 第三种方式...使用propertyFilter...进行过滤... * */ JsonConfig config=new JsonConfig(); config.setJsonPropertyFilter(new PropertyFilter() { /** * arg0:属性拥有者... * arg1: 属性名字... * arg2: 属性值... * * */ @Override public boolean apply(Object arg0, String arg1, Object arg2) { // TODO Auto-generated method stub return arg0 instanceof User && arg1.equals("userid"); } }); JSONObject json=JSONObject.fromObject(user,config); System.out.println(json.toString()); } }
以上就是三种实现属性过滤的方式...可以根据情况选用特定的方式....
3.从网络上获取Json数据...
一般在开发中,我们的数据格式一般都是保存在服务器上的...那么我们需要通过URL来获取数据信息....下面这里只是提供了一个方法..其实就是通过URL的形式来完成数据信息的传递.这样我们就得到了Json数据...
public static String loadJson (String url) { StringBuilder json = new StringBuilder(); try { URL urlObject = new URL(url); URLConnection uc = urlObject.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); String inputLine = null; while ( (inputLine = in.readLine()) != null) { json.append(inputLine); } in.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return json.toString(); }
但是仅仅得到的是整个JSON的字符串,只是对整个结果集的一个处理,那么如何获取其中的各个属性呢?这才是至关重要的....
4.解析Json数据获取各个属性...
下面就是获取每一个Json值,然后进行保存的一个过程...这里我采用JsonArray的方式,将Json数据转换成Json数组的形式...
当然我们也可以使用Google官方为我们提供了Gson..调用其中内部的方法就能够获取各个属性信息...不过需要使用到其他的jar...这里我就不进行介绍了...使用Gson只需要调用一些方法其实就能搞定了....大家可以百度...
package json; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //这是一段Json数据...比如说就通过URL获取到的... String json="{'user':" + "[ " + "{'userid':'1' , 'username':'darker' , 'userpassword':'49681888'}," + "{'userid':'2' , 'username':'darker_1' , 'userpassword':'49681888'}," + "{'userid':'3' , 'username':'darker_2' , 'userpassword':'49681888'} " + "]" + "}"; //s字符串包含着每个字段的所有属性... String s[]=new String[]{"userid","username","userpassword"}; //以集合的方式,将数据信息进行保存... List<Map<String, Object>>list=new ArrayList<Map<String,Object>>(); /** * * 网上有很多方式是JSONObject jsonObject=new JSONObject(json);的方式来初始化对象... * 但是这种方式在我使用的json-lib-2.4版本下会直接报错... * 因此使用了fromObject方法进行对象的初始化... * * */ JSONObject jsonObject=JSONObject.fromObject(json); try { //将Json数据转化成数组的形式...user就是整个数组名称... JSONArray array=jsonObject.getJSONArray("user"); for(int i=0;i<array.size();i++){ /** * 这里使用了optXXX方法...目的是避免发生异常.. * 如果我们使用getXXX方法的话,那么key值就必须存在...一旦不存在就会异常... * 因此使用了optXXX方法... * */ /** * 下面这个对象保存的是这些数据...对应不同的i值...数据也就不同... * i=0; * * {'userid':'1' , 'username':'darker' , 'userpassword':'49681888'} * * i=1 * * {'userid':'2' , 'username':'darker_1' , 'userpassword':'49681888'} * * 以此类推... * */ JSONObject object= (JSONObject) array.opt(i); Map<String, Object>map=new HashMap<String, Object>(); for(String str:s){ //循环遍历,把所有的值都保存在Map中 //把object的值进行保存... map.put(str, object.get(str)); } //最后使用List保存Map list.add(map); } } catch (Exception e) { // TODO: handle exception } } }
其实解析各个属性的思路还有很多,比如说我们获取到Json字符串之后,通过Java Bean进行转换...然后覆盖其中的toJsonString()方法...自然也可以获取到其中的各个属性...在实际的开发中Json数据有可能更加的复杂,但是我们只要根据具体数据进行具体分析,就能够从数据中获取各个属性,来完成更多的操作...
比如说更复杂的...我们想要获取rect1中的所对应的数据信息...
package json; import net.sf.json.JSONObject; public class Json { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub /* * 读取多重Json.... * */ String jsonStr = "{states:{rect1:{type:'start',text:{text:'开始'}, " + "attr:{ x:448, y:105, width:50, height:50}, " + "props:{text:{value:'开始'},temp1:{value:''}," + "temp2:{value:''}}},rect2:{type:'state',text:{text:'camel_element'}, " + "attr:{ x:431, y:224, width:100, height:50}, props:{text:{value:'camel_element'}," + "temp1:{value:'http://www/baidu.com'}}},rect3:{type:'end',text:{text:'结束'}, " + "attr:{ x:454, y:365, width:50, height:50}, props:{text:{value:'结束'}," + "temp1:{value:''},temp2:{value:''}}}},paths:{path4:{from:'rect1',to:'rect2', dots:[]," + "text:{text:'TO camel_element'},textPos:{x:0,y:-10}, props:{text:{value:''}}}," + "path5:{from:'rect2',to:'rect3', dots:[],text:{text:'TO 结束'},textPos:{x:0,y:-10}, " + "props:{text:{value:''}}}},props:{props:{name:{value:'新建流程'},key:{value:''}," + "desc:{value:''}}}}"; JSONObject jsonObj = JSONObject.fromObject(jsonStr); System.out.println(jsonObj.getJSONObject("states").getJSONObject("rect1")); } }
这里其实就是给大家一个思路而已,具体的情况还是需要我们具体进行思考...只要思考,没有解决不了的问题....
Author By: Darker