在对JavaBean做序列化时,我们可能在某些场景希望前后兼容性好一些。比如所有的javaBean都序列化后保存在数据库,用的时候需要反序列化创建。随着业务的发展,数据模型可能会进行变更,那么原来的数据进行反序列化时可能会遇到版本不一致的问题。作者在对drools的Fact建模时就遇到了类似问题。那么有没有一种兼容性比较好的序列化方案同时又不失javaBean的基础特性(getter和setter函数)呢?答案是肯定的。
其实,简单来说,HashMap的序列化时兼容性应该是最好的,因为它就是简单的键值对,不需要版本的概念。但毕竟不是JavaBean对象,那么能不能融合着两者呢?哈哈,当然可以,废话不多说,先上代码。
1 public abstract class AbstractBean implements Serializable { 2 protected HashMapWrapper internalHashMapData = null; 3 4 public HashMapWrapper getInternalHashMapData() { 5 return internalHashMapData; 6 } 7 8 public void setInternalHashMapData(HashMapWrapper internalHashMapData) { 9 this.internalHashMapData = internalHashMapData; 10 } 11 }
AbstractBean这个抽象类,保护一个HashMapWrapper的字段,用来存储所有字段的数据。
1 public class FirstJavaBean extends AbstractBean { 2 public String getName(){ 3 return this.internalHashMapData.getString("name"); 4 } 5 public void setName(String name){ 6 this.internalHashMapData.setString("name",name); 7 } 8 }
继承AbstractBean时,包含了一个name字段,要特别注意getter和setter的实现方式。都是通过internalHashMapData存取数据的。这样做可以把数据的存储和数据的接口解耦了。如果FirstJavaBean接口变更了,对数据存取没有任何影响,序列化时就可以消除版本不一致带来的问题了!这个方法还是非常巧妙的有没有。
下面是对hashMap的简单封装,由于该封装后期不再变化,对序列化也不会有任何影响。
1 public class HashMapWrapper implements Serializable { 2 private HashMap<String,Object> internalHashMap; 3 public HashMapWrapper(){ 4 internalHashMap = new HashMap<String,Object>(0); 5 } 6 public void setInternalHashMap(HashMap<String,Object> hashMap){ 7 this.internalHashMap = hashMap; 8 } 9 public HashMap<String,Object> getInternalHashMap(){ 10 return this.internalHashMap; 11 } 12 13 public BigDecimal getBigDecimal(String key){ 14 return getBigDecimalOr(key,null); 15 } 16 public BigDecimal getBigDecimalOr(String key,BigDecimal defaultValue){ 17 Object value = internalHashMap.get(key); 18 if(value instanceof BigDecimal){ 19 return (BigDecimal)value; 20 }else 21 return defaultValue; 22 } 23 24 public void setBigDecimal(String key,BigDecimal value){ 25 internalHashMap.put(key,value); 26 } 27 28 public BigInteger getBigInteger(String key){ 29 return getBigIntegerOr(key,null); 30 } 31 public BigInteger getBigIntegerOr(String key,BigInteger defaultValue){ 32 Object value = internalHashMap.get(key); 33 if(value instanceof BigInteger){ 34 return (BigInteger)value; 35 }else 36 return defaultValue; 37 } 38 public void setBigInteger(String key,BigInteger value){ 39 internalHashMap.put(key,value); 40 } 41 public Boolean getBooleanOr(String key,Boolean defaultValue){ 42 Object value = internalHashMap.get(key); 43 if(value instanceof Boolean){ 44 return (Boolean)value; 45 }else 46 return defaultValue; 47 } 48 public Boolean getBoolean(String key){ 49 return getBooleanOr(key,null); 50 } 51 52 public void setBoolean(String key,Boolean value){ 53 internalHashMap.put(key,value); 54 } 55 public Byte getByte(String key){ 56 return getByteOr(key,null); 57 } 58 public Byte getByteOr(String key,Byte defaultValue){ 59 Object value = internalHashMap.get(key); 60 if(value instanceof Byte){ 61 return (Byte)value; 62 }else 63 return defaultValue; 64 } 65 66 public void setByte(String key,Byte value){ 67 internalHashMap.put(key,value); 68 } 69 public Character getCharacterOr(String key,Character defaultValue){ 70 Object value = internalHashMap.get(key); 71 if(value instanceof Character){ 72 return (Character)value; 73 }else 74 return defaultValue; 75 } 76 public Character getCharacter(String key){ 77 return getCharacterOr(key,null); 78 } 79 public void setCharacter(String key,Character value){ 80 internalHashMap.put(key,value); 81 } 82 public Date getDateOr(String key, Date defaultValue){ 83 Object value = internalHashMap.get(key); 84 if(value instanceof Date){ 85 return (Date)value; 86 }else 87 return defaultValue; 88 } 89 public Date getDate(String key){ 90 return getDateOr(key,null); 91 } 92 public void setDate(String key,Date value){ 93 internalHashMap.put(key,value); 94 } 95 96 public Double getDouble(String key){ 97 return getDoubleOr(key,null); 98 } 99 public Double getDoubleOr(String key,Double defaultValue){ 100 Object value = internalHashMap.get(key); 101 if(value instanceof Double){ 102 return (Double)value; 103 }else 104 return defaultValue; 105 } 106 public void setDouble(String key,Double value){ 107 internalHashMap.put(key,value); 108 } 109 public Float getFloatOr(String key,Float defaultValue){ 110 Object value = internalHashMap.get(key); 111 if(value instanceof Float){ 112 return (Float)value; 113 }else 114 return defaultValue; 115 } 116 public Float getFloat(String key){ 117 return getFloatOr(key,null); 118 } 119 public void setFloat(String key,Float value){ 120 internalHashMap.put(key,value); 121 } 122 public Integer getIntegerOr(String key,Integer defaultValue){ 123 Object value = internalHashMap.get(key); 124 if(value instanceof Integer){ 125 return (Integer)value; 126 }else 127 return defaultValue; 128 } 129 public Integer getInteger(String key){ 130 return getIntegerOr(key,null); 131 } 132 public void setInteger(String key,Integer value){ 133 internalHashMap.put(key,value); 134 } 135 public Long getLongOr(String key,Long defaultValue){ 136 Object value = internalHashMap.get(key); 137 if(value instanceof Long){ 138 return (Long)value; 139 }else 140 return defaultValue; 141 } 142 public Long getLong(String key){ 143 return getLongOr(key,null); 144 } 145 public void setLong(String key,Long value){ 146 internalHashMap.put(key,value); 147 } 148 public Short getShortOr(String key,Short defaultValue){ 149 Object value = internalHashMap.get(key); 150 if(value instanceof Short){ 151 return (Short)value; 152 }else 153 return defaultValue; 154 } 155 public Short getShort(String key){ 156 return getShortOr(key,null); 157 } 158 public void setShort(String key,Short value){ 159 internalHashMap.put(key,value); 160 } 161 public String getStringOr(String key,String defaultValue){ 162 Object value = internalHashMap.get(key); 163 if(value instanceof String){ 164 return (String)value; 165 }else 166 return defaultValue; 167 } 168 public String getString(String key){ 169 return getStringOr(key,null); 170 } 171 public void setString(String key,String value){ 172 internalHashMap.put(key,value); 173 } 174 public boolean getBooleanValueOr(String key,boolean defaultValue){ 175 Object value = internalHashMap.get(key); 176 if(value instanceof Boolean){ 177 return (Boolean)value; 178 }else 179 return defaultValue; 180 } 181 public boolean getBooleanValue(String key){ 182 return getBooleanValueOr(key,false); 183 } 184 public void setBooleanValue(String key,boolean value){ 185 internalHashMap.put(key,value); 186 } 187 public byte getByteValueOr(String key,byte defaultValue){ 188 Object value = internalHashMap.get(key); 189 if(value instanceof Byte){ 190 return (Byte)value; 191 }else 192 return defaultValue; 193 } 194 public byte getByteValue(String key){ 195 return getByteValueOr(key,(byte)0); 196 } 197 public void setByteValue(String key,byte value){ 198 internalHashMap.put(key,value); 199 } 200 public char getCharValueOr(String key,char defaultValue){ 201 Object value = internalHashMap.get(key); 202 if(value instanceof Character){ 203 return (Character)value; 204 }else 205 return defaultValue; 206 } 207 public char getCharValue(String key){ 208 return getCharValueOr(key,(char)0); 209 } 210 public void setCharValue(String key,char value){ 211 internalHashMap.put(key,value); 212 } 213 public double getDoubleValueOr(String key,double defaultValue){ 214 Object value = internalHashMap.get(key); 215 if(value instanceof Double){ 216 return (Double)value; 217 }else 218 return defaultValue; 219 } 220 public double getDoubleValue(String key){ 221 return getDoubleValueOr(key,0.0d); 222 } 223 public void setDoubleValue(String key,double value){ 224 internalHashMap.put(key,value); 225 } 226 public float getFloatValueOr(String key,float defaultValue){ 227 Object value = internalHashMap.get(key); 228 if(value instanceof Float){ 229 return (Float)value; 230 }else 231 return defaultValue; 232 } 233 public float getFloatValue(String key){ 234 return getFloatValueOr(key,0.0f); 235 } 236 public void setFloatValue(String key,float value){ 237 internalHashMap.put(key,value); 238 } 239 public int getIntValueOr(String key,int defaultValue){ 240 Object value = internalHashMap.get(key); 241 if(value instanceof Integer){ 242 return (Integer)value; 243 }else 244 return defaultValue; 245 } 246 public int getIntValue(String key){ 247 return getIntValueOr(key,0); 248 } 249 public void setIntValue(String key,int value){ 250 internalHashMap.put(key,value); 251 } 252 public long getLongValueOr(String key,long defaultValue){ 253 Object value = internalHashMap.get(key); 254 if(value instanceof Long){ 255 return (Long)value; 256 }else 257 return defaultValue; 258 } 259 public long getLongValue(String key){ 260 return getLongValueOr(key,0L); 261 } 262 public void setLongValue(String key,long value){ 263 internalHashMap.put(key,value); 264 } 265 public short getShortValueOr(String key,short defaultValue){ 266 Object value = internalHashMap.get(key); 267 if(value instanceof Short){ 268 return (Short)value; 269 }else 270 return defaultValue; 271 } 272 public short getShortValue(String key){ 273 return getShortValueOr(key,(short)0); 274 } 275 public void setShortValue(String key,short value){ 276 internalHashMap.put(key,value); 277 } 278 public Object getObjectOr(String key,Object defaultValue){ 279 Object value = internalHashMap.get(key); 280 if( value == null ){ 281 return defaultValue; 282 }else { 283 return internalHashMap.get(key); 284 } 285 } 286 public Object getObject(String key){ 287 return internalHashMap.get(key); 288 } 289 public void setObject(String key,Object value){ 290 internalHashMap.put(key,value); 291 } 292 public <T> T getAsResultOr(String key,T defaultValue){ 293 T value = (T) internalHashMap.get(key); 294 if(value == null){ 295 return defaultValue; 296 }else { 297 return value; 298 } 299 } 300 public <T> T getAsResult(String key){ 301 return (T) internalHashMap.get(key); 302 } 303 public <T> void setAsValue(String key,T value){ 304 internalHashMap.put(key,value); 305 } 306 307 public boolean getboolean(String key) { 308 return getBooleanValue(key); 309 } 310 public void setboolean(String key,boolean value){ 311 setBooleanValue(key,value); 312 } 313 public byte getbyte(String key) { 314 return getByteValue(key); 315 } 316 public void setbyte(String key,byte value){ 317 setByteValue(key,value); 318 } 319 public char getchar(String key) { 320 return getCharValue(key); 321 } 322 public void setchar(String key,char value){ 323 setCharValue(key,value); 324 } 325 public double getdouble(String key) { 326 return getDoubleValue(key); 327 } 328 public void setdouble(String key,double value){ 329 setDoubleValue(key,value); 330 } 331 public float getfloat(String key) { 332 return getFloatValue(key); 333 } 334 public void setfloat(String key,float value){ 335 setFloatValue(key,value); 336 } 337 public int getint(String key) { 338 return getIntValue(key); 339 } 340 public void setint(String key,int value){ 341 setIntValue(key,value); 342 } 343 public long getlong(String key) { 344 return getLongValue(key); 345 } 346 public void setlong(String key,long value){ 347 setLongValue(key,value); 348 } 349 public short getshort(String key) { 350 return getShortValue(key); 351 } 352 public void setshort(String key,short value){ 353 setShortValue(key,value); 354 } 355 }