package com.jiuqi.lbsinterface.json; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; import com.jiuqi.lbsinterface.utils.Base64; import com.jiuqi.lbsinterface.utils.Base64DecodingException; import com.jiuqi.lbsinterface.ws.WSConsts; public class JSONConvertor { private static <T> boolean isWrapClass(Class<T> clazs){ if(clazs == String.class|| clazs == Integer.class|| clazs == Long.class|| clazs == Double.class|| clazs == Short.class|| clazs == Character.class|| clazs == Boolean.class|| clazs == Float.class|| clazs == Byte.class )return true; return false; } private static <T> boolean isWrapClass(Object clazs){ return isWrapClass(clazs.getClass()); } @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object serializable(Object t){ if(t==null)return null; if(isWrapClass(t))return t; if(t.getClass().isEnum())return t; JSONObject result = new JSONObject(); try{ result.put(WSConsts.CLASS_TAG, t.getClass().getName()); } catch(JSONException e1){ e1.printStackTrace(); } Class clazs = t.getClass(); List<Field> fields = getFields(clazs); for(Field field : fields){ field.setAccessible(true); Object value = null; try{ value = field.get(t); } catch(IllegalAccessException e){ e.printStackTrace(); throw new RuntimeException("通过反射访问"+field+"属性时发生错误", e); } if(field.getType().isPrimitive()||value instanceof String){ try{ result.put(field.getName(), value); } catch(JSONException e){ throw new IllegalArgumentException("JSON赋值时发生错误", e); } }else if(field.getType() == UUID.class) { if (value != null) { UUID uuid = (UUID)value; long[] bitsArray = new long[]{uuid.getMostSignificantBits(), uuid.getLeastSignificantBits()}; try { JSONArray uuidObject = new JSONArray(bitsArray); result.put(field.getName(), uuidObject); } catch (JSONException e) { throw new IllegalArgumentException("JSON赋值时发生错误." + e.getMessage(), e); } } }else if(field.getType().isEnum()){ try{ result.put(field.getName(), value); } catch(JSONException e){ throw new IllegalArgumentException("JSON赋值时发生错误", e); } }else if(field.getType().isSynthetic()||field.getType().isMemberClass()||field.getType().isLocalClass()){ try{ result.put(field.getName(), serializable(value)); } catch(JSONException e){ throw new IllegalArgumentException("JSON赋值时发生错误", e); } }else if(field.getType().isArray()){ try{ Class clazss = field.getType().getComponentType(); if(clazss.isPrimitive()||isWrapClass(clazss)){ if (clazss == byte.class) { byte[] barray = (byte[]) value; String base64 = Base64.encode(barray); result.put(field.getName(), base64); } else { if(value != null) { result.put(field.getName(), new JSONArray(value)); } } }else{ Object[] ary = (Object[])value; JSONArray jsonArray = new JSONArray(); if(ary!=null){ for(Object object : ary){ jsonArray.put(serializable(object)); } } result.put(field.getName(), jsonArray); } } catch(JSONException e){ throw new IllegalArgumentException("JSON赋值时发生错误", e); } }else if (field.getType()==Date.class) { if (value != null) { try { result.put(field.getName(), ((Date)value).getTime()); } catch (JSONException e) { throw new IllegalArgumentException("JSON Date类型赋值时发生错误", e); } } }else { try{ result.put(field.getName(), serializable(value)); } catch(JSONException e){ throw new IllegalArgumentException("JSON赋值时发生错误", e); } } } return result; } public static <T> T unSerializable(Class<T> t,String arg){ try{ return unSerializable(t, new JSONObject(arg)); } catch(JSONException e){ throw new IllegalArgumentException("传入的字符串不是一个正确的JSON格式,请检查格式是否正确"+arg.toString()); } } @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T> T unSerializable(Class<T> t,Object arg){ if(arg==null)return null; if(isWrapClass(t)){ return arg==null ? null : (T)arg; } if(t.isEnum()){ for(T e:t.getEnumConstants()){ if(((Enum)e).name().equals(arg)){ return e; } } return null; } if(t.isPrimitive()){ return (T)arg; } if(t.isArray()){ Class<?> componentType = t.getComponentType(); if (componentType == byte.class && arg instanceof String) { String base64 = (String)arg; try { return (T) Base64.decode(base64); } catch (Base64DecodingException e) { return null; } }else { JSONArray array = (JSONArray)arg; if(array.length()==0)return null; if (componentType == byte.class) { /** * 为兼容2012-12-03之前的上传数据, * 正式发版时可以去掉 */ byte[] byteArray = new byte[array.length()]; try { for(int i=0; i<array.length() ;i++){ byteArray[i] = (byte)array.getInt(i); } return (T) byteArray; } catch (JSONException e) { e.printStackTrace(); throw new IllegalArgumentException("JSON取值时发生错误"+array, e); } } else { if(componentType.equals(Object.class)){ try{ JSONObject jo = array.getJSONObject(0); String c = jo.getString("class"); componentType = Class.forName(c, true, Thread.currentThread().getContextClassLoader()); }catch(Exception e){ try { Object jo = array.get(0); componentType = jo.getClass(); } catch (JSONException e1) { } } } T objs = (T)Array.newInstance(componentType, array.length()); for(int i=0;i<array.length();i++){ try{ Object val = null; if (componentType ==Long.class) { val = array.getLong(i); } else { val = array.get(i); } Array.set(objs,i,unSerializable(componentType, val)); } catch(JSONException e){ e.printStackTrace(); throw new IllegalArgumentException("JSON取值时发生错误"+array, e); } } return objs; } } } if(t == UUID.class) { JSONArray uuidObject = (JSONArray)arg; UUID uuid; try { uuid = new UUID(uuidObject.getLong(0), uuidObject.getLong(1)); } catch (JSONException e) { e.printStackTrace(); throw new IllegalArgumentException("JSON取值时发生错误." + uuidObject, e); } return (T) uuid; } if (t == Date.class) { long time = (Long)arg; return (T)new Date(time); } return unSerializable(t, (JSONObject)arg); } private static <T> List<Field> getFields(Class<T> t){ List<Field> list = new ArrayList<Field>(); for(Field field : t.getDeclaredFields()){ boolean isSerializable = isSerializable(field); if(isSerializable)continue; list.add(field); } if(t.getSuperclass()!=Object.class){ list.addAll(getFields(t.getSuperclass())); } return list; } private static boolean isSerializable(Field field) { if (Modifier.isStatic(field.getModifiers())) return false; Miss miss = field.getAnnotation(Miss.class); boolean isMiss = false; if(miss!=null){ isMiss = miss.value(); } return isMiss; } /** * 将json类型转换成指定的类 * * @param <T> * @param t * @param arg * @return T */ public static <T> T unSerializable(Class<T> t,JSONObject arg){ if(arg==null)return null; try{ T obj = createNewInstance(t); for(Field field : getFields(t)){ try{ if(Modifier.isFinal(field.getModifiers()))continue; String fieldName = field.getName(); if(!arg.has(fieldName))continue; Object fieldValue = arg.get(fieldName); if(fieldValue==null)continue; field.setAccessible(true); field.set(obj, unSerializable(field.getType(), fieldValue)); } catch(IllegalAccessException e){ throw new RuntimeException("使用反射机制访问" + t.getName() + "类的字段时发生错误:"+field.getName(), e); } catch(SecurityException e){ throw new RuntimeException("对类"+t.getName()+"进行反射操作时发生安全异常:"+field.getName(),e); } catch(IllegalArgumentException e){ throw new RuntimeException("使用反射机制访问" + t.getName() + "类的字段时发生错误"+field.getName(), e); } catch(JSONException e){ throw new IllegalArgumentException("传入的JSON参数不正确,请检查格式是否正确,或者字段名是否缺失"+arg.toString(),e); } } return obj; } catch(InstantiationException e){ throw new RuntimeException("类" + t.getName() + "需要提供一个无参public的构造函数,并且不能是抽象类或者接口或者数组", e); } catch(IllegalAccessException e){ throw new RuntimeException("使用反射机制访问" + t.getName() + "类的字段时发生错误", e); } } private static <T> T createNewInstance(Class<T> t) throws InstantiationException, IllegalAccessException { try { Constructor<T> constructor = t.getDeclaredConstructor(); constructor.setAccessible(true); return constructor.newInstance(); } catch (SecurityException e1) { throw new RuntimeException(String.format("不能通过反射访问类型 %s及其无参构造函数",t.getName())); } catch (NoSuchMethodException e1) { throw new RuntimeException(String.format("类型%s必须有个无参构造函数",t.getName())); } catch (IllegalArgumentException e) { throw new RuntimeException(String.format("调用类型%s的无参构造函数失败", t.getName())); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw new RuntimeException(String.format("调用类型%s的无参构造函数失败,%s", t.getName(),cause==null?"":cause.getMessage())); } } }