We solved this problem as follows:
Like @keuleJ, we create our own SerializerFactory (see below), but we do not return com.caucho.hessian.io.BigDecimalDeserializer because it does not check for null.
public class BigDecimalSerializerFactory extends AbstractSerializerFactory { private BigDecimalSerializer bigDecimalSerializer = new BigDecimalSerializer(); private BigDecimalDeserializer bigDecimalDeserializer = new BigDecimalDeserializer(); @Override public Serializer getSerializer(Class cl) throws HessianProtocolException { if (BigDecimal.class.isAssignableFrom(cl)) { return bigDecimalSerializer; } return null; } @Override public Deserializer getDeserializer(Class cl) throws HessianProtocolException { if (BigDecimal.class.isAssignableFrom(cl)) { return bigDecimalDeserializer; } return null; }
}
Then we defined our own deserializer. It differs from the implementation of com.couchos # s in one, checking to see if it is null. Need to extend AbstractStringValueDeserialize!
public class BigDecimalDeserializer extends AbstractStringValueDeserializer { @Override public Class getType() { return BigDecimal.class; } @Override protected Object create(String value) { if (null != value) { return new BigDecimal(value); } else { return null; } }
}
The serializer only passes the BigDecimal view to String:
Public class BigDecimalSerializer extends AbstractSerializer {
@Override public void writeObject(Object obj, AbstractHessianOutput out) throws IOException { if (obj == null) out.writeNull(); else { Class cl = obj.getClass(); if (out.addRef(obj)) return; int ref = out.writeObjectBegin(cl.getName()); BigDecimal bi = (BigDecimal) obj; if (ref < -1) { out.writeString("value"); out.writeString(bi.toString()); out.writeMapEnd(); } else { if (ref == -1) { out.writeInt(1); out.writeString("value"); out.writeObjectBegin(cl.getName()); } out.writeString(bi.toString()); } } }
}
This implementation works for us not only for BigDecimal, but also for joda DateTime.
To use this, you must add the Serializer Factory to
SerializerFactory serializerFactory = newSerializerFactory(); serializerFactory.addFactory(new BigDecimalSerializerFactory());
You must do this both on the server side and on the client side!
HINT! In our case, we had a difficult problem with BigDecimal and DateTime. So stacktraces and debugging views were weird. Therefore, if you use "non-standard" objects, check them to serialize them!