转json操作
json教程系列(1)-使用json所要用到的jar包
json是个非常重要的数据结构,在web开发中应用十分广泛。我觉得每个人都应该好好的去研究一下json的底层实现,基于这样的认识,金丝燕网推出了一个关于json的系列教程,分析一下json的相关内容,希望大家能有所收获。首先给大家说一下使用json前的准备工作,需要准备下面的六个jar包:
commons-lang-1.0.4.jar
commons-collections-2.1.jar
commons-beanutils-1.8.0.jar
json-lib-2.4.jar
ezmorph-1.0.6.jar
commons-logging-1.1.jar
需要说明几点:
(1)json-lib最新版本可以从这个地方下载:http://sourceforge.net/projects/json-lib/files/json-lib/
(2)ezmorph是一个简单的java类库,用于将一种bean转换成另外一种bean。其动态bean的实现依赖于commons-beanutils包。ezmorph可以在这个地方下载源码:http://sourceforge.net/projects/ezmorph/files/ezmorph/
(3)commons-beanutils是操作JavaBean的类库,依赖于commons-collections。
(4)commons-collections类库是各种集合类和集合工具类的封装。
(本文于2015年5月29日修订)
json教程系列(2)-生成JSONObject的方法
生成JSONObject一般有两种方式,通过javabean或者map类型来生成。如下面的例子
publicclassUser
{
publicStringusername;
publicStringpassword;
publicStringgetUsername()
{
returnusername;
}
publicvoidsetUsername(Stringusername)
{
this.username=username;
}
publicStringgetPassword()
{
returnpassword;
}
publicvoidsetPassword(Stringpassword)
{
this.password=password;
}
}
importjava.util.HashMap;
importnet.sf.json.JSONObject;
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Useruser=newUser();
user.setUsername("root");
user.setPassword("1234");
JSONObjectjson1=JSONObject.fromObject(user);
System.out.println(json1.toString());
HashMap<Object,Object>userMap=newHashMap<Object,Object>();
userMap.put("username","root");
userMap.put("password","1234");
JSONObjectjson2=JSONObject.fromObject(userMap);
System.out.println(json2.toString());
}
}
下面从源码层次分析一下JSONObject.fromObject()方法:
publicstaticJSONObjectfromObject(Objectobject)
{
returnfromObject(object,newJsonConfig());
}
此函数可以接受的参数类型为:JSONformattedstrings,Maps,DynaBeansandJavaBeans。
【注意】DynaBeans是commons-beanutils定义的动态bean。DynaBean并不是Java中所定义的Bean,而是一种"假"的Bean。因为它并不是通过getXXX和setXXX方法,对XXX属性进行取值和设值的。
如果object是其他类型的参数呢?比如说数字,逻辑值,非json格式的字符串,那么将生产空的JSONObject对象。
if(JSONUtils.isNumber(object)||JSONUtils.isBoolean(object)||JSONUtils.isString(object))
{
returnnewJSONObject();
}
JSONObject的构造函数有两个:
publicJSONObject()
{
this.properties=newListOrderedMap();
}
publicJSONObject(booleanisNull)
{
this();
this.nullObject=isNull;
}
不过,说实话,第二个构造函数使用情况很少。
json教程系列(3)-JSONObject的过滤设置
我们通常对一个json串和java对象进行互转时,经常会有选择性的过滤掉一些属性值。例如下面的类:
publicclassPerson
{
privateStringname;
privateStringaddress;
privateStringsex;
publicStringgetAddress()
{
returnaddress;
}
publicvoidsetAddress(Stringaddress)
{
this.address=address;
}
publicStringgetName()
{
returnname;
}
publicvoidsetName(Stringname)
{
this.name=name;
}
publicStringgetSex()
{
returnsex;
}
publicvoidsetSex(Stringsex)
{
this.sex=sex;
}
}
如果我想过滤address属性怎么办?
方法一:实现JSONString接口
importnet.sf.json.JSONString;
publicclassPersonimplementsJSONString
{
privateStringname;
privateStringsex;
privateStringaddress;
publicStringtoJSONString()
{
return"{\"name\":\""+name+"\",\"sex\":\""+sex+"\"}";
}
publicStringgetAddress()
{
returnaddress;
}
publicvoidsetAddress(Stringaddress)
{
this.address=address;
}
publicStringgetName()
{
returnname;
}
publicvoidsetName(Stringname)
{
this.name=name;
}
publicStringgetSex()
{
returnsex;
}
publicvoidsetSex(Stringsex)
{
this.sex=sex;
}
}
importnet.sf.json.JSONObject;
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Personperson=newPerson();
person.setName("swiftlet");
person.setSex("men");
person.setAddress("china");
JSONObjectjson=JSONObject.fromObject(person);
System.out.println(json.toString());
}
}
方法二:设置jsonconfig实例,对包含和需要排除的属性进行添加或删除。
importnet.sf.json.JSONObject;
importnet.sf.json.JsonConfig;
publicclassTest
{
publicstaticvoidmain(Stringargs[])
{
Personperson=newPerson();
person.setName("swiftlet");
person.setSex("men");
person.setAddress("china");
JsonConfigjsonConfig=newJsonConfig();
jsonConfig.setExcludes(newString[]
{"address"});
JSONObjectjson=JSONObject.fromObject(person,jsonConfig);
System.out.println(json.toString());
}
}
方法三:使用propertyFilter实例过滤属性。
importnet.sf.json.JSONObject;
importnet.sf.json.JsonConfig;
importnet.sf.json.util.PropertyFilter;
publicclassTest
{
publicstaticvoidmain(Stringargs[])
{
Personperson=newPerson();
person.setName("swiftlet");
person.setSex("men");
person.setAddress("china");
JsonConfigjsonConfig=newJsonConfig();
jsonConfig.setJsonPropertyFilter(newPropertyFilter(){
publicbooleanapply(Objectsource,Stringname,Objectvalue)
{
returnsourceinstanceofPerson&&name.equals("address");
}
});
JSONObjectjson=JSONObject.fromObject(person,jsonConfig);
System.out.println(json.toString());
}
}
json教程系列(4)-optXXX方法的使用
在JSONObject获取value有多种方法,如果key不存在的话,这些方法无一例外的都会抛出异常。如果在线环境抛出异常,就会使出现error页面,影响用户体验,针对这种情况最好是使用optXXX方法。
getString方法会抛出异常,如下所示:
publicStringgetString(Stringkey)
{
verifyIsNull();
Objecto=get(key);
if(o!=null)
{
returno.toString();
}
thrownewJSONException("JSONObject["+JSONUtils.quote(key)+"]notfound.");
}
getInt方法会抛出异常,如下所示:
publicintgetInt(Stringkey)
{
verifyIsNull();
Objecto=get(key);
if(o!=null)
{
returnoinstanceofNumber?((Number)o).intValue():(int)getDouble(key);
}
thrownewJSONException("JSONObject["+JSONUtils.quote(key)+"]isnotanumber.");
}
getDouble方法会抛出异常,如下所示:
publicdoublegetDouble(Stringkey)
{
verifyIsNull();
Objecto=get(key);
if(o!=null)
{
try
{
returnoinstanceofNumber?((Number)o).doubleValue():Double.parseDouble((String)o);
}
catch(Exceptione)
{
thrownewJSONException("JSONObject["+JSONUtils.quote(key)+"]isnotanumber.");
}
}
thrownewJSONException("JSONObject["+JSONUtils.quote(key)+"]isnotanumber.");
}
getBoolean方法会抛出异常,如下所示:
publicbooleangetBoolean(Stringkey)
{
verifyIsNull();
Objecto=get(key);
if(o!=null)
{
if(o.equals(Boolean.FALSE)||(oinstanceofString&&((String)o).equalsIgnoreCase("false")))
{
returnfalse;
}
elseif(o.equals(Boolean.TRUE)||(oinstanceofString&&((String)o).equalsIgnoreCase("true")))
{
returntrue;
}
}
thrownewJSONException("JSONObject["+JSONUtils.quote(key)+"]isnotaBoolean.");
}
JSONObject有很多optXXX方法,比如optBoolean,optString,optInt。它们的意思是,如果JsonObject有这个属性,则返回这个属性,否则返回一个默认值。下面以optString方法为例说明一下其底层实现过程:
publicStringoptString(Stringkey)
{
verifyIsNull();
returnoptString(key,"");
}
publicStringoptString(Stringkey,StringdefaultValue)
{
verifyIsNull();
Objecto=opt(key);
returno!=null?o.toString():defaultValue;
}