Java序列化和反序列化工具类
项目中数据传输需要序列化,趁机写了个序列化工具
调用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public static void main(String[] args) throws InterruptedException { try { Map<String, Object> data = new HashMap<String, Object>(); data.put("list", new ArrayList<String>()); data.put("key", "aaa"); data.put("int", 13); data.put("double", 13.0D); data.put("long", 13L); data.put("float", 13.0F); data.put("user", new User()); byte[] res = ParamEncoder.getInstance().encode(data); data = (Map<String, Object>) ParamDecoder.getInstance().decoder(res); System.out.println(data); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } |
打印消息:
1 |
{int=13, list=[], double=13.0, long=13, float=13.0, user=net.code2048.common.TestEncode$User@247510e7, key=aaa} |
下面是实现类:
ParamEncoder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
package net.code2048.common; import org.w3c.dom.Document; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.*; /** * 序列化返回值 * * @author 破晓(www.code2048.net) * @version 1.0_debug */ @SuppressWarnings("rawtypes") public class ParamEncoder { private static ParamEncoder instance; private IParamResolve _outEncoder; public static ParamEncoder getInstance() { if (instance == null) instance = new ParamEncoder(); return instance; } /** * 序列化返回值 * * @param data * @return * @throws Exception */ public byte[] encode(Object data) throws Exception { return encode(data, null); } /** * 序列化返回值 * * @param data * @param outEncoder * @return * @throws Exception */ public byte[] encode(Object data, IParamResolve outEncoder) throws Exception { _outEncoder = outEncoder; ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); writeAll(data, dos); _outEncoder = null; return bos.toByteArray(); } public void writeAll(Object result, DataOutputStream dos) throws Exception { if (result == null){ dos.writeByte(ParamType.NULL); } else if (_outEncoder != null && _outEncoder.encode(result, dos)){ return; } else if (result instanceof Boolean){ dos.writeByte(ParamType.BOOLEAN); // 写入Boolean类型 dos.writeBoolean((Boolean) result); } else if (result instanceof String){ dos.writeByte(ParamType.STRING); // 写入String类型 dos.writeUTF(result.toString()); } else if (result instanceof Integer){ dos.writeByte(ParamType.INT); // 写入Integer类型 dos.writeInt((Integer) result); } else if (result instanceof Double){ dos.writeByte(ParamType.DOUBLE); // 写入Double类型 dos.writeDouble((Double) result); } else if (result instanceof Long){ dos.writeByte(ParamType.LONG); // 写入Long类型 dos.writeLong((Long) result); } else if (result instanceof Date){ dos.writeByte(ParamType.DATE); // 写入Date类型 dos.writeLong(((Date) result).getTime()); } else if (result instanceof List) { writeList((List) result, dos); // 写入List类型 } else if (result instanceof Map){ writeMap((Map) result, dos); // 写入Map类型 } else if (result instanceof Float){ dos.writeByte(ParamType.FLOAT); // 写入Float类型 dos.writeFloat((Float) result); } else if (result instanceof Short){ dos.writeByte(ParamType.SHORT); // 写入Short类型 dos.writeShort((Short) result); } else if (result instanceof Byte){ dos.writeByte(ParamType.BYTE); // 写入BYTE类型 dos.writeByte((Byte) result); // } else if (result instanceof Character){ // dos.writeByte(ParamType.CHARACTER); // 写入Character类型 // dos.writeChar((Character) result); } else if (result instanceof BigDecimal){ dos.writeByte(ParamType.BIG_DECIMAL); // 写入BigDecimal类型 dos.writeUTF(result.toString()); }else if (result instanceof Calendar){ dos.writeByte(ParamType.CALENDAR); // 写入Calendar类型 dos.writeLong(((Calendar) result).getTime().getTime()); } else if (result instanceof Document) { TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); // t.setOutputProperty("encoding", "UTF-8");// ByteArrayOutputStream bos = new ByteArrayOutputStream(); t.transform(new DOMSource((Document) result), new StreamResult(bos)); dos.writeByte(ParamType.XML); // 写入类型 dos.writeUTF(bos.toString("UTF-8")); } else if (result instanceof Byte[] || result instanceof byte[]) { byte[] b; if (result instanceof Byte[]) { b = new byte[((Byte[]) result).length]; int loop = 0; for (Byte ib : (Byte[]) result) { b[loop++] = ib.byteValue(); } } else b = ((byte[]) result); int len = b.length; dos.writeByte(ParamType.BYTE_ARRAY); // 写入类型 dos.writeInt(len); dos.write(b, 0, len); } else if (result.getClass().isArray()) { writeArray(result, dos); } else { writeModel(result, dos); } } public void writeModel(Object model, DataOutputStream dos) throws Exception { dos.writeByte(ParamType.MODEL);// 写入类型 dos.writeUTF(model.getClass().getName()); Map<String, Method> map = CacheUtil.getModelGetter(model); dos.writeInt(map.size()); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Object key = iterator.next();//key dos.writeUTF(key.toString()); writeAll(map.get(key).invoke(model), dos); } } public void writeArray(Object lobj, DataOutputStream dos) throws Exception { String comType = lobj.getClass().getComponentType().getName(); int len = Array.getLength(lobj); dos.writeByte(ParamType.ARRAY);// 写入类型 dos.writeUTF(comType); // 写入数组子类型 dos.writeInt(len); for (int i=0; i<len; i++) { writeAll(Array.get(lobj, i), dos); } } public void writeList(List lst, DataOutputStream dos) throws Exception { dos.writeByte(ParamType.LIST);// 写入类型 dos.writeInt(lst.size()); for (Object item : lst) { writeAll(item, dos); } } public void writeMap(Map map, DataOutputStream dos) throws Exception { dos.writeByte(ParamType.MAP);// 写入类型 dos.writeInt(map.size()); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Object key = iterator.next();//key dos.writeUTF(key.toString()); writeAll(map.get(key), dos); } } public void writeObject(Object obj, DataOutputStream dos) throws Exception { dos.writeByte(ParamType.MAP); // 写入类型 Field[] fs = obj.getClass().getFields(); dos.writeInt(fs.length); for (Field item : fs) { dos.writeUTF(item.getName()); writeAll(item.get(obj), dos); } } } |
ParamDecoder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
package net.code2048.common; import org.w3c.dom.Document; import org.xml.sax.InputSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.beans.PropertyDescriptor; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.StringReader; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.*; /** * 解析参数 * * @author 破晓(www.code2048.net) */ @SuppressWarnings({"rawtypes", "unchecked"}) public class ParamDecoder { private static ParamDecoder instance; private IParamResolve _outDecoder; private static Map<String, Class> baseTypeMap; static{ baseTypeMap = new HashMap<String, Class>(); baseTypeMap.put("byte", byte.class); baseTypeMap.put("short", short.class); baseTypeMap.put("int", int.class); baseTypeMap.put("float", float.class); baseTypeMap.put("long", long.class); baseTypeMap.put("double", double.class); baseTypeMap.put("char", char.class); baseTypeMap.put("boolean", boolean.class); } public static ParamDecoder getInstance() { if (instance == null) instance = new ParamDecoder(); return instance; } public Object decoder(byte[] data) throws Exception { return decoder(data, null); } /** * 解析数据 * * @return * @throws Exception */ public Object decoder(byte[] data, IParamResolve outDecoder) throws Exception { _outDecoder = outDecoder; ByteArrayInputStream bis = new ByteArrayInputStream(data); DataInputStream dis = new DataInputStream(bis); // if (dis.available() != dis.readInt()) // throw new Exception("丢包了"); Object result = readAll(dis); _outDecoder = null; return result; } /** * 构建数据 * * @param dis * @return * @throws Exception */ public Object readAll(DataInputStream dis) throws Exception { Object param = null; Object outer = null; byte type = dis.readByte(); if (type != ParamType.NULL && _outDecoder != null) { outer = _outDecoder.decode(type, dis); } if (type == ParamType.NULL){ param = null; } else if (outer != null){ return outer; } else if (type == ParamType.BOOLEAN){ param = dis.readBoolean(); } else if (type == ParamType.STRING){ param = dis.readUTF(); } else if (type == ParamType.INT){ param = dis.readInt(); } else if (type == ParamType.DOUBLE){ param = dis.readDouble(); } else if (type == ParamType.LONG){ param = dis.readLong(); } else if (type == ParamType.DATE){ param = new Date(dis.readLong()); } else if (type == ParamType.LIST){ param = readList(dis); } else if (type == ParamType.MAP){ param = readMap(dis); } else if (type == ParamType.FLOAT){ param = dis.readFloat(); } else if (type == ParamType.SHORT){ param = dis.readShort(); } else if (type == ParamType.BYTE){ param = dis.readByte(); } else if (type == ParamType.BIG_DECIMAL){ String v = dis.readUTF(); param = new BigDecimal(v); } else if (type == ParamType.CALENDAR){ Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(dis.readLong()); param = cal; } else if (type == ParamType.BYTE_ARRAY) { int len = dis.readInt(); byte[] b = new byte[len]; dis.read(b, 0, len); param = b; } else if (type == ParamType.XML) { String xmlStr = dis.readUTF(); StringReader sr = new StringReader(xmlStr); InputSource is = new InputSource(sr); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; builder = factory.newDocumentBuilder(); Document doc = builder.parse(is); param = doc; } else if (type == ParamType.MODEL){ param = readModel(dis); } else if (type == ParamType.ARRAY){ param = readArray(dis); } else if (type == ParamType.UNFOUND){ param = dis.readUTF(); } else { System.out.println(type); throw new Exception("参数格式错误"); } return param; } /** * 读取List * * @param dis * @return * @throws Exception */ public List readList(DataInputStream dis) throws Exception { List lst = new ArrayList(); int len = dis.readInt(); for (int loop = 0; loop < len; loop++) { lst.add(readAll(dis)); } return lst; } /** * 读取数组 * * @param dis * @return * @throws Exception */ public Object readArray(DataInputStream dis) throws Exception { String comType = dis.readUTF(); int len = dis.readInt(); Class cla; if(baseTypeMap.containsKey(comType)) cla = baseTypeMap.get(comType); else cla = Class.forName(comType); Object obj = Array.newInstance(cla, len); for (int loop = 0; loop < len; loop++) { Array.set(obj, loop, readAll(dis)); } return obj; } /** * 读取Object * * @param dis * @return * @throws Exception */ public Map<String, Object> readMap(DataInputStream dis) throws Exception { Map<String, Object> map = new HashMap<String, Object>(); int len = dis.readInt(); for (int loop = 0; loop < len; loop++) { map.put(dis.readUTF(), readAll(dis)); } return map; } /** * 读取Model * * @param dis * @return * @throws Exception */ public Object readModel(DataInputStream dis) throws Exception { Object model = null; String nameSpace = dis.readUTF(); Class cls = Class.forName(nameSpace); model = cls.newInstance(); int len = dis.readInt(); String fieldName = null; Method method; Map<String, Field> filedMap = CacheUtil.getFieldCache(cls); PropertyDescriptor pd = null; Object param = null; try { for (int loop = 0; loop < len; loop++) { fieldName = dis.readUTF(); param = readAll(dis); if (filedMap.containsKey(fieldName)) { pd = new PropertyDescriptor(fieldName, cls); method = pd.getWriteMethod(); //param = pd.getPropertyType().cast(param); // 强制类型转换 method.invoke(model, new Object[]{param}); } else { System.out.println("warning: ###类" + nameSpace + "中,属性:【" + fieldName + "】 未定义,所以没有对该属性进行赋值"); } } } catch (IllegalArgumentException e) { if (filedMap != null && filedMap.containsKey(fieldName)) throw new ClassCastException(nameSpace + "类中的属性:" + fieldName + "类型转换失败 ,正确的类型为:" + filedMap.get(fieldName).getType() + "但实际为:" + ((param != null) ? param.getClass().getName() : "null")); else throw e; } return model; } } |
工具及常量类:
ParamType.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
package net.code2048.common; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.w3c.dom.Document; /** * 数据类型 * * @author 破晓(www.code2048.net) */ @SuppressWarnings("rawtypes") public class ParamType { ////////////////////////////////////////////////////////////////// // 公有 类型 0 - 30 ////////////////////////////////////////////////////////////////// /** * 未知类型 */ public static final byte UNFOUND = 127; /** * null */ public static final byte NULL = 0; /** * Boolean */ public static final byte BOOLEAN = 1; /** * String */ public static final byte STRING = 2; /** * ByteArray, [] */ public static final byte BYTE_ARRAY = 3; /** * Date */ public static final byte DATE = 4; /** * Calendar */ public static final byte CALENDAR = 5; /** * Map */ public static final byte MAP = 6; /** * xml */ public static final byte XML = 7; /** * list */ public static final byte LIST = 8; /** * array */ public static final byte ARRAY = 9; /** * Character */ public static final byte CHARACTER = 10; /** * model */ public static final byte MODEL = 30; ////////////////////////////////////////////////////////////////// // 数字 类型 31 - 50 ////////////////////////////////////////////////////////////////// /** * byte */ public static final byte BYTE = 31; /** * short */ public static final byte SHORT = 32; /** * int */ public static final byte INT = 33; /** * float */ public static final byte FLOAT = 34; /** * double */ public static final byte DOUBLE = 35; /** * long */ public static final byte LONG = 36; /** * BigDecimal */ public static final byte BIG_DECIMAL = 37; ////////////////////////////////////////////////////////////////// // 其他 类型 51 - 99 ////////////////////////////////////////////////////////////////// private static Map<Class, Class> typeMap = null; public static Map<Class, Class> getTypeMap() throws Exception { if (typeMap == null) { typeMap = new HashMap<Class, Class>(); typeMap.put(ArrayList.class, List.class); typeMap.put(Class.forName("com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl"), Document.class); } return typeMap; } } |
IParamResolve.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package net.code2048.common; import java.io.DataInputStream; import java.io.DataOutputStream; /** * 外部解析器接口 * * @author 破晓(www.code2048.net) */ public interface IParamResolve { /** * 序列化 * * @param param * @param dos * @return */ public boolean encode(Object param, DataOutputStream dos) throws Exception; /** * 反序列化 * * @param dos * @return * @throws Exception */ public Object decode(byte type, DataInputStream dos) throws Exception; /** * 设置外部解析器 */ public void setOutParamResolve(IParamResolve value); } |
CacheUtil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package net.code2048.common; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * * @author 破晓(www.code2048.net) * */ public class CacheUtil { /** * 缓存数据模型的所有属性 */ private static Map<String, Map<String, Field>> modelFieldCache = new HashMap<String, Map<String, Field>>(); private static Map<String, Map<String, Method>> modelGetterCache = new HashMap<String, Map<String, Method>>(); @SuppressWarnings("rawtypes") public static Map<String, Field> getFieldCache(Class cls) { String nameSpace = cls.getName(); if (modelFieldCache.containsKey(nameSpace)) return modelFieldCache.get(nameSpace); Field[] fileds; Class tempCls = cls; Map<String, Field> filedMap = new HashMap<String, Field>(); while (!tempCls.equals(Object.class)) { try { fileds = tempCls.getDeclaredFields(); for (Field tf : fileds) { filedMap.put(tf.getName(), tf); } tempCls = tempCls.getSuperclass(); } catch (Exception e) { System.out.println(e); } } modelFieldCache.put(nameSpace, filedMap); return filedMap; } /** * 获取model的所有getter方法 * * @param model * @return * @throws Exception */ @SuppressWarnings("rawtypes") public static Map<String, Method> getModelGetter(Object model) throws Exception { Class cls = model.getClass(); String className = cls.getName(); if (modelGetterCache.containsKey(className)) { return modelGetterCache.get(className); } Map<String, Method> map = new HashMap<String, Method>(); Map<String, Field> filedMap = getFieldCache(cls); Collection<Field> fileds = filedMap.values(); PropertyDescriptor pd = null; for (Field tf : fileds) { if (tf.isEnumConstant()) continue; int tm = tf.getModifiers(); if (Modifier.isStatic(tm) || Modifier.isPublic(tm)) continue; String fieldName = tf.getName(); pd = new PropertyDescriptor(fieldName, cls); map.put(fieldName, pd.getReadMethod()); } modelGetterCache.put(className, map); return map; } } |