首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何配置Jackson将Long序列化为字符串,而不是整数或双精度?

如何配置Jackson将Long序列化为字符串,而不是整数或双精度?
EN

Stack Overflow用户
提问于 2017-11-04 05:44:21
回答 2查看 5.3K关注 0票数 3

我们之前使用的框架(云端点)自动将java.lang.Long序列化为JSON字符串(同时将整数和双精度数保留为JSON数字)。我们正在迁移以使用更标准的Jackson序列化框架。

为了向后兼容,我们需要Jackson能够将Long序列化为String,同时将整数和Double默认保留为JSON数字。我在杰克逊身上看不到任何这样做的功能。这个是可能的吗?

EN

回答 2

Stack Overflow用户

发布于 2017-11-04 06:08:22

Long.classlong.class使用自定义序列化程序

代码语言:javascript
复制
public static class LongSerializer extends JsonSerializer<Long> {
    @Override
    public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(value.toString());
    }
}

public static class LongDeserializer extends JsonDeserializer<Long> {
    @Override
    public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        return p.getValueAsLong();
    }
}

您需要向您的映射器注册它们:

代码语言:javascript
复制
public static void main(String[] args) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();

    SimpleModule module = new SimpleModule();
    module.addSerializer(long.class, new LongSerializer());
    module.addSerializer(Long.class, new LongSerializer());
    module.addDeserializer(long.class, new LongDeserializer());
    module.addDeserializer(Long.class, new LongDeserializer());
    objectMapper.registerModule(module);

    Test test = new Test();
    String json = objectMapper.writeValueAsString(test);
    System.out.println(json);
}
票数 4
EN

Stack Overflow用户

发布于 2017-11-04 19:48:45

选项1.定制序列化程序

@teppic答案应该适用于大多数情况,但是

  1. 你不需要定制的反序列化程序。缺省反序列化程序可以处理字符串,ToStringSerializer.instance);
  2. You可以使用com.fasterxml.jackson.databind.ser.std.ToStringSerializer serializermodule.addSerializer(Long.class,ToStringSerializer.instance);module.addSerializer(long.class,Long.class);因为自定义序列化程序方法实际上不能处理另一个自定义序列化程序使用this JsonGenerator method时的情况

(JsonGenerator) g.writeNumber((Long)值);

这里最重要的边缘情况是long[].class

静态类MyBean { long val = 1;//运行正常"1“Long val2 = 2L;//运行正常"2”long[] = { 1,2 };//不工作1,2 }

所以你实际上可以

代码语言:javascript
复制
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));
}

选项2.自定义JsonFactory和JsonGenerator

但话又说回来,这对你来说足够了吗?你确定没有人会尝试使用jsonGenerator.writeNumber(long)吗?或者你有其他的类,实际上是默认使用它的吗?因此,100%可行的解决方案是在ObjectMapper上注册自定义JsonFactory,并使用2个被覆盖的方法_createGenerator_createUTF8Generator

代码语言:javascript
复制
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);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47104817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档