Option 1. Custom serializer
@teppic answer should work for most of the cases, but
You don't need custom deserializer. The default deserializer can handle String => long
Can use com.fasterxml.jackson.databind.ser.std.ToStringSerializer serializer
module.addSerializer(Long.class, ToStringSerializer.instance);
module.addSerializer(long.class, ToStringSerializer.instance);
You will get edge cases, because custom serializer approach actually can't handle cases when another custom serializer uses this JsonGenerator method
(JsonGenerator) g.writeNumber((long)value);
And the most important edge case here is long[].class
static class MyBean {
long val = 1; // works fine "1"
Long val2 = 2L; // works fine "2"
long[] vals = {1,2}; // doesn't work [1,2]
}
So you actually can
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, ToStringSerializer.instance);
module.addSerializer(long.class, ToStringSerializer.instance);
module.addSerializer(long[].class, new JsonSerializer<long[]>(){
@Override
public final void serialize(
long[] value, JsonGenerator g, SerializerProvider provider)
throws IOException {
g.writeStartArray();
for (int i = 0, len = value.length; i < len; ++i)
g.writeString(String.valueOf(value[i]));
g.writeEndArray();
}
});
// register every other serializers that use
// (JsonGenerator) g.writeNumber((long)value);
// like AtomicLong, if you use it in your code
mapper.registerModule(module);
MyBean bean = new MyBean();
String json = mapper.writeValueAsString(bean);
MyBean myBean2 = mapper.readValue(json, MyBean.class);
System.out.println(json);
System.out.println(myBean2);
System.out.println(mapper.writeValueAsString(myBean2));
}
Option 2. Custom JsonFactory and JsonGenerator
But then again, is it enough for you and are you sure nobody will ever try to use jsonGenerator.writeNumber(long) or do you have some other class, that is actually using it by default? So the 100% working solution would be to register custom JsonFactory on ObjectMapper with 2 overridden methods _createGenerator and _createUTF8Generator
JsonFactory factory = new JsonFactory(){
@Override
protected JsonGenerator _createGenerator(Writer out, IOContext ctxt)
throws IOException {
WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt,
_generatorFeatures, _objectCodec, out){
@Override
public void writeNumber(long l) throws IOException {
writeString(String.valueOf(l));
}
};
return _internalSuperSetup(gen);
}
@Override
protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt)
throws IOException {
UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt,
_generatorFeatures, _objectCodec, out){
@Override
public void writeNumber(long l) throws IOException {
writeString(String.valueOf(l));
}
};
return _internalSuperSetup(gen);
}
// reuse code from _createUTF8Generator and _createGenerator super methods
private JsonGenerator _internalSuperSetup(JsonGenerator gen){
if (_characterEscapes != null) gen.setCharacterEscapes(_characterEscapes);
SerializableString rootSep = _rootValueSeparator;
if (rootSep != DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR)
gen.setRootValueSeparator(rootSep);
return gen;
}
};
ObjectMapper mapper = new ObjectMapper(factory);