Java 考虑到性能,我应该如何获得ObjectWriter来将POJO序列化为JSON?

Java 考虑到性能,我应该如何获得ObjectWriter来将POJO序列化为JSON?,java,json,serialization,jackson,jackson-databind,Java,Json,Serialization,Jackson,Jackson Databind,他们说: 如果所有配置 在任何读或写调用之前发生实例的。如果 映射器实例的配置在首次使用后被修改, 更改可能会生效,也可能不会生效,配置调用本身也会生效 可能会失败。如果您需要使用不同的配置,您有两个 主要可能性: 构建并使用ObjectReader进行阅读,ObjectWriter进行写作。 这两种类型都是完全不可变的,您可以自由创建新实例 使用以下任一工厂方法进行不同配置: ObjectMapper或读写器本身。新建 ObjectReaders和ObjectWriter是一个非常轻量级的操作

他们说:

如果所有配置 在任何读或写调用之前发生实例的。如果 映射器实例的配置在首次使用后被修改, 更改可能会生效,也可能不会生效,配置调用本身也会生效 可能会失败。如果您需要使用不同的配置,您有两个 主要可能性:

构建并使用ObjectReader进行阅读,ObjectWriter进行写作。 这两种类型都是完全不可变的,您可以自由创建新实例 使用以下任一工厂方法进行不同配置: ObjectMapper或读写器本身。新建 ObjectReaders和ObjectWriter是一个非常轻量级的操作,因此 通常适合根据需要在每次呼叫的基础上创建这些, 用于配置JSON的可选缩进

每次我需要新的ObjectWriter时都打这个电话可以吗

jsonString = new MyObjectWriter().objectWriter().writeValueAsString(myPojo);
其中MyObjectWriter看起来像这样:

public class MyObjectWriter {
    public ObjectWriter objectWriter()
    {
        return new ObjectMapper()
                .writer()
                .with(SerializationFeature.INDENT_OUTPUT)
                .with(JsonGenerator.Feature.IGNORE_UNKNOWN);
    }
}

我应该保留ObjectMapper的副本吗?ObjectWriter?

类似的文档说明这是一种非常便宜的操作,您可以“按每次调用”进行操作。让我们看看每种方法背后都有什么

jsonString = new MyObjectWriter().objectWriter().writeValueAsString(myPojo);
  • ObjectMapper.writer
    -使用
    SerializationConfig
    ObjectMapper
    创建新的
    ObjectWriter
  • ObjectWriter.with
    -创建新的
    ObjectWriter
    ,它基于
    caller
    实例以及必须启用的新功能。如果给定的功能已启用,则返回相同的实例。如果功能更改配置,将创建并返回新的
    ObjectWriter
让我们看一个示例应用程序,它显示了给定的场景:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.util.Collections;
import java.util.Map;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        ObjectWriter writer0 = mapper.writer();
        ObjectWriter writer1 = writer0.with(SerializationFeature.INDENT_OUTPUT);
        ObjectWriter writer2 = writer1.with(SerializationFeature.INDENT_OUTPUT);
        ObjectWriter writer3 = writer2.with(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);

        Map<String, Long> map = Collections.singletonMap("key", 123L);
        System.out.println(writer0 + " = " + writer0.writeValueAsString(map));
        System.out.println(writer1 + " = " + writer1.writeValueAsString(map));
        System.out.println(writer2 + " = " + writer2.writeValueAsString(map));
        System.out.println(writer3 + " = " + writer3.writeValueAsString(map));


        ObjectMapper mapper1 = new ObjectMapper();
        mapper1.enable(SerializationFeature.INDENT_OUTPUT);
        mapper1.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);

        ObjectWriter writer4 = mapper1.writer();
        System.out.println(writer4 + " = " + writer4.writeValueAsString(map));
    }
}
请注意,第二个(
writer1
)和第三个(
writer2
)实例(
com.fasterxml.jackson.databind)。ObjectWriter@2a5ca609
)是相同的。它们还生成相同的
JSON
负载


因此,使用
ObjectMapper
的第一个实例,我们创建并配置了
ObjectWriter
。但主要只使用最后一个。所有中间人都已离开,等待由
GC
收集。那样做没有意义。最好创建
ObjectMapper
实例,对其进行配置,并通过调用
writer()
方法创建已配置的
ObjectWriter
。您可以为已配置的
ObjectMapper
实例创建类似
Factory
的类,您可以使用这些实例生成
ObjectWriter
-s。

否,您应该保留
ObjectMapper
的实例,这样我就可以创建一个
私有静态最终ObjectMapper mapper=new ObjectMapper()然后让我的
objectWriter()
方法
返回mapper.writer().with(SerializationFeature.INDENT\u OUTPUT)。with(JsonGenerator.Feature.IGNORE\u UNKNOWN)则任何不更改功能的调用方都将获得相同的ObjectWriter实例。正确吗?@braveterry,每次调用方法
objectWriter(){return mapper.writer().with(SerializationFeature.INDENT_OUTPUT)。with(jsongGenerator.Feature.IGNORE_UNKNOWN)}
new
objectWriter
实例时都将返回。使用这些特性创建
ObjectMapper
实例要好得多,您的方法可以如下所示:
objectWriter(){return mapper.writer();}
。每次调用此方法时,都会得到
ObjectWriter
的新实例。主要的一点是,在调用带有(FEATURE1).带有(FEATURE2).
的mapper.writer()的链调用过程中,我们在幕后创建了许多
ObjectWriter
-es。