博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JSONObject转换分析
阅读量:5009 次
发布时间:2019-06-12

本文共 17416 字,大约阅读时间需要 58 分钟。

net.sf.json.JSONObject采用反射的方式,对POJO进行转换。JSONObject类实现了JSON、Map和Comparable接口,如下:

class JSONObject extends AbstractJSON implements JSON, Map, Comparable

以Person类为例分析源码:

public class Person {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}

 

 

fromObject(Object object)方法

代码实现主要在JSONObject defaultBeanProcessing(Object bean, JsonConfig jsonConfig)方法中,如下:

private static JSONObject defaultBeanProcessing(Object bean, JsonConfig jsonConfig) {      Class beanClass = bean.getClass(); //获取类对象 class net.sf.json.mytest.Person      PropertyNameProcessor propertyNameProcessor = jsonConfig.findJsonPropertyNameProcessor( beanClass );            Collection exclusions = jsonConfig.getMergedExcludes( beanClass );//需要排除的类信息,[metaClass, declaringClass, class]      JSONObject jsonObject = new JSONObject();      try{         PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors( bean );//获取POJO类的描述信息,包括属性、属性对应的读写操作, //[java.beans.PropertyDescriptor[name=age; propertyType=int; readMethod=public int net.sf.json.mytest.Person.getAge(); writeMethod=public void net.sf.json.mytest.Person.setAge(int)], //java.beans.PropertyDescriptor[name=class; propertyType=class java.lang.Class; readMethod=public final native java.lang.Class java.lang.Object.getClass()], //java.beans.PropertyDescriptor[name=name; propertyType=class java.lang.String; readMethod=public java.lang.String net.sf.json.mytest.Person.getName(); writeMethod=public void net.sf.json.mytest.Person.setName(java.lang.String)]]         PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter();         //循环对所有属性进行处理         for( int i = 0; i < pds.length; i++ ){            boolean bypass = false;            //获取属性名            String key = pds[i].getName();            if( exclusions.contains( key ) ){               continue;            }            if( jsonConfig.isIgnoreTransientFields() && isTransientField( key, beanClass ) ){               continue;            }            Class type = pds[i].getPropertyType();            try { pds[i].getReadMethod(); }            catch( Exception e ) {               // bug 2565295               String warning = "Property '" + key + "' of "+ beanClass+" has no read method. SKIPPED";               fireWarnEvent( warning, jsonConfig );               log.info( warning );               continue;            }            if( pds[i].getReadMethod() != null ){               Object value = PropertyUtils.getProperty( bean, key );               if( jsonPropertyFilter != null && jsonPropertyFilter.apply( bean, key, value ) ){                  continue;               }               JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor(                     beanClass, type, key );               if( jsonValueProcessor != null ){                  value = jsonValueProcessor.processObjectValue( key, value, jsonConfig );                  bypass = true;                  if( !JsonVerifier.isValidJsonValue( value ) ){                     throw new JSONException( "Value is not a valid JSON value. " + value );                  }               }               if( propertyNameProcessor != null ){                  key = propertyNameProcessor.processPropertyName( beanClass, key );               }               //设置属性值               setValue( jsonObject, key, value, type, jsonConfig, bypass );            }else{               String warning = "Property '" + key + "' of "+ beanClass+" has no read method. SKIPPED";               fireWarnEvent( warning, jsonConfig );               log.info( warning );            }         }        .......      }catch( JSONException jsone ){         removeInstance( bean );         fireErrorEvent( jsone, jsonConfig );         throw jsone;      }catch( Exception e ){         removeInstance( bean );         JSONException jsone = new JSONException( e );         fireErrorEvent( jsone, jsonConfig );         throw jsone;      }      return jsonObject;   }

 

toBean(JSONObject object, Class clazz)方法

由JSONObject对象转为对应类实例,关键代码在Object toBean( JSONObject jsonObject, JsonConfig jsonConfig )中,如下:

 public static Object toBean( JSONObject jsonObject, JsonConfig jsonConfig ) {

if( jsonObject == null || jsonObject.isNullObject() ){         return null;      }      Class beanClass = jsonConfig.getRootClass();//类对象      Map classMap = jsonConfig.getClassMap();      if( beanClass == null ){         return toBean( jsonObject );      }      if( classMap == null ){         classMap = Collections.EMPTY_MAP;      }      Object bean = null;      try{         if( beanClass.isInterface() ){            if( !Map.class.isAssignableFrom( beanClass ) ){               throw new JSONException( "beanClass is an interface. " + beanClass );            }else{               bean = new HashMap();            }         }else{            bean = jsonConfig.getNewBeanInstanceStrategy() //实例化                  .newInstance( beanClass, jsonObject );         }      }catch( JSONException jsone ){         throw jsone;      }catch( Exception e ){         throw new JSONException( e );      }      Map props = JSONUtils.getProperties( jsonObject );//属性及属性类型  {name=class java.lang.String, age=class java.lang.Integer}      PropertyFilter javaPropertyFilter = jsonConfig.getJavaPropertyFilter();      for( Iterator entries = jsonObject.names( jsonConfig )            .iterator(); entries.hasNext(); ){         String name = (String) entries.next();//属性名         Class type = (Class) props.get( name );//属性类型         Object value = jsonObject.get( name );//属性值,如果属性值为null,返回的值为JSONNull对象         if( javaPropertyFilter != null && javaPropertyFilter.apply( bean, name, value ) ){            continue;         }         String key = Map.class.isAssignableFrom( beanClass )               && jsonConfig.isSkipJavaIdentifierTransformationInMapKeys() ? name               : JSONUtils.convertToJavaIdentifier( name, jsonConfig );         PropertyNameProcessor propertyNameProcessor = jsonConfig.findJavaPropertyNameProcessor( beanClass );         if( propertyNameProcessor != null ){            key = propertyNameProcessor.processPropertyName( beanClass, key );         }         //设置实例对象的属性(处理各种情况)         try{            if( Map.class.isAssignableFrom( beanClass ) ){
//Map对象单独处理 // no type info available for conversion if( JSONUtils.isNull( value ) ){ setProperty( bean, key, value, jsonConfig ); }else if( value instanceof JSONArray ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, List.class ), jsonConfig ); }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( jsonConfig.isHandleJettisonEmptyElement() && "".equals( value ) ){ setProperty( bean, key, null, jsonConfig ); }else{ setProperty( bean, key, value, jsonConfig ); } }else{ Class targetClass = resolveClass(classMap, key, name, type); JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( targetClass ); jsc.setClassMap( classMap ); if( targetClass != null ){ setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); }else{ setProperty( bean, key, toBean( (JSONObject) value ), jsonConfig ); } } }else{ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor( bean, key );//获取属性描述 //java.beans.PropertyDescriptor[name=name; propertyType=class java.lang.String; readMethod=public java.lang.String net.sf.json.mytest.Person.getName(); writeMethod=public void net.sf.json.mytest.Person.setName(java.lang.String)] if( pd != null && pd.getWriteMethod() == null ){ log.info( "Property '" + key + "' of "+ bean.getClass()+" has no write method. SKIPPED." ); continue; } if( pd != null ){ Class targetType = pd.getPropertyType(); if( !JSONUtils.isNull( value ) ){ if( value instanceof JSONArray ){ //JSONArray值 if( List.class.isAssignableFrom( pd.getPropertyType() ) ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, pd.getPropertyType() ), jsonConfig ); }else if( Set.class.isAssignableFrom( pd.getPropertyType() ) ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, pd.getPropertyType() ), jsonConfig ); }else{ setProperty( bean, key, convertPropertyValueToArray( key, value, targetType, jsonConfig, classMap ), jsonConfig ); } }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) //基本类型 || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( pd != null ){ if( jsonConfig.isHandleJettisonEmptyElement() && "".equals( value ) ){ setProperty( bean, key, null, jsonConfig ); }else if( !targetType.isInstance( value ) ){ setProperty( bean, key, morphPropertyValue( key, value, type, targetType ), jsonConfig ); }else{ setProperty( bean, key, value, jsonConfig );//对String进行处理 } }else if( beanClass == null || bean instanceof Map ){ setProperty( bean, key, value, jsonConfig ); }else{ log.warn( "Tried to assign property " + key + ":" + type.getName() + " to bean of class " + bean.getClass() .getName() ); } }else{ if( jsonConfig.isHandleJettisonSingleElementArray() ){ JSONArray array = new JSONArray().element( value, jsonConfig ); Class newTargetClass = resolveClass(classMap, key, name, type); JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( newTargetClass ); jsc.setClassMap( classMap ); if( targetType.isArray() ){ setProperty( bean, key, JSONArray.toArray( array, jsc ), jsonConfig ); }else if( JSONArray.class.isAssignableFrom( targetType ) ){ setProperty( bean, key, array, jsonConfig ); }else if( List.class.isAssignableFrom( targetType ) || Set.class.isAssignableFrom( targetType ) ){ jsc.setCollectionType( targetType ); setProperty( bean, key, JSONArray.toCollection( array, jsc ), jsonConfig ); }else{ setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); } }else{ if( targetType == Object.class || targetType.isInterface() ) { Class targetTypeCopy = targetType; targetType = findTargetClass( key, classMap ); targetType = targetType == null ? findTargetClass( name, classMap ) : targetType; targetType = targetType == null && targetTypeCopy.isInterface() ? targetTypeCopy : targetType; } JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( targetType ); jsc.setClassMap( classMap ); setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); } } }else{ if( type.isPrimitive() ){ // assume assigned default value log.warn( "Tried to assign null value to " + key + ":" + type.getName() ); setProperty( bean, key, JSONUtils.getMorpherRegistry() .morph( type, null ), jsonConfig ); }else{ setProperty( bean, key, null, jsonConfig ); } } }else{ // pd is null if( !JSONUtils.isNull( value ) ){ if( value instanceof JSONArray ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, List.class ), jsonConfig ); }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( beanClass == null || bean instanceof Map || jsonConfig.getPropertySetStrategy() != null || !jsonConfig.isIgnorePublicFields() ){ setProperty( bean, key, value, jsonConfig ); }else{ log.warn( "Tried to assign property " + key + ":" + type.getName() + " to bean of class " + bean.getClass() .getName() ); } }else{ if( jsonConfig.isHandleJettisonSingleElementArray() ){ Class newTargetClass = resolveClass(classMap, key, name, type); JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( newTargetClass ); jsc.setClassMap( classMap ); setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); }else{ setProperty( bean, key, value, jsonConfig ); } } }else{ if( type.isPrimitive() ){ // assume assigned default value log.warn( "Tried to assign null value to " + key + ":" + type.getName() ); setProperty( bean, key, JSONUtils.getMorpherRegistry() .morph( type, null ), jsonConfig ); }else{ setProperty( bean, key, null, jsonConfig ); } } } } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( "Error while setting property=" + name + " type " + type, e ); } } return bean; }

 另外,Map转JSONObject问题:

会将Map结构({key=value})转换为json格式(“key”:"value")。

(1)java中的null,会转换为JSONNull对象,不能直接将该对象转为String。

(2)net.sf.json.JSONObject不支持Map中key为null的情况。

举例如下:

import java.util.HashMap;import java.util.Map;import net.sf.json.JSONNull;import net.sf.json.JSONObject;public class Test {    public static void main(String[] args) {        Map
data1 = new HashMap<>();// data1.put(null, "empty"); //报JSON keys cannot be null. data1.put("ts", null); System.out.println(data1.toString()); if(data1.get("ts")==null){ System.out.println("Map中的null"); } JSONObject jsonObject = JSONObject.fromObject(data1); System.out.println(jsonObject.toString()); if(JSONNull.getInstance().equals(jsonObject.get("ts"))){ System.out.println("Map中的null,转为net.sf.json.JSONObject后,变成net.sf.json.JSONNull"); } Map
map = (Map
) JSONObject.toBean(jsonObject, HashMap.class); System.out.println(map.get("ts").toString()); // Map
map = (Map
) JSONObject.toBean(jsonObject, HashMap.class);// System.out.println(map.get("ts").toString()); //java.lang.ClassCastException: net.sf.json.JSONNull cannot be cast to java.lang.String }}

  结果:

{ts=null}Map中的null{
"ts":null}Map中的null,转为net.sf.json.JSONObject后,变成net.sf.json.JSONNull

 

转载于:https://www.cnblogs.com/shuimuzhushui/p/8901919.html

你可能感兴趣的文章
TCP三次握手、四次握手
查看>>
认识System,System32,Syswow64
查看>>
Jmeter如何把CSV文件的路径设置成一个变量,且变量的值是一个相对路径
查看>>
免费的自动构建CI
查看>>
iOS10 app连接不上网络的问题
查看>>
结对开发之电梯调度最终稿(徐梦迪&刘博)
查看>>
simple java mail
查看>>
信息建模
查看>>
二进制中1的个数
查看>>
Android ListView 滚动时背景变黑色
查看>>
《机器学习》第一章 引言 笔记加总结
查看>>
每天一点点之vue框架开发 - 引入bootstrap
查看>>
【刷题】洛谷 P3806【模板】点分治1
查看>>
mysql 二进制文件增量备份
查看>>
使用ffmpeg步骤
查看>>
RabbitMQ inequivalent arg 'durable' for exchange 'csExchange' in vhost '/': received
查看>>
《2017中国云计算评测报告》
查看>>
有木有兄弟在研究HTML5和css3啊?进来唠叨一下,分享一下你的资源
查看>>
Hibernate 中一对多和多对多映射
查看>>
EL表达式_详解
查看>>