考虑到性能,我应该如何获得用于将 POJO 序列化为 JSON 的 ObjectWriter?
With performance in mind, how should I get an ObjectWriter for serializing POJOs to JSON?
com.fasterxml.jackson.databind.ObjectMapper JavaDocs 说:
Mapper instances are fully thread-safe provided that ALL configuration
of the instance occurs before ANY read or write calls. If
configuration of a mapper instance is modified after first usage,
changes may or may not take effect, and configuration calls themselves
may fail. If you need to use different configuration, you have two
main possibilities:
Construct and use ObjectReader for reading, ObjectWriter for writing.
Both types are fully immutable and you can freely create new instances
with different configuration using either factory methods of
ObjectMapper, or readers/writers themselves. Construction of new
ObjectReaders and ObjectWriters is a very light-weight operation so it
is usually appropriate to create these on per-call basis, as needed,
for configuring things like optional indentation of 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?
就像文档说的那样,这是非常便宜的操作,您可以做到 "on per call basis"。让我们看看每种方法背后都有什么。
ObjectMapper.writer
- 使用来自 ObjectMapper
. 的 SerializationConfig
创建新的 ObjectWriter
ObjectWriter.with
- 创建基于 caller
实例的新 ObjectWriter
以及必须启用的新功能。如果已启用给定功能,则返回相同的实例。如果功能更改配置 - 创建并返回新 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));
}
}
以上应用打印:
com.fasterxml.jackson.databind.ObjectWriter@2ed94a8b = {"key":123}
com.fasterxml.jackson.databind.ObjectWriter@2a5ca609 = {
"key" : 123
}
com.fasterxml.jackson.databind.ObjectWriter@2a5ca609 = {
"key" : 123
}
com.fasterxml.jackson.databind.ObjectWriter@20e2cbe0 = {
"key" : "123"
}
com.fasterxml.jackson.databind.ObjectWriter@68be2bc2 = {
"key" : "123"
}
注意,第二个 (writer1
) 和第三个 (writer2
) 个实例 (com.fasterxml.jackson.databind.ObjectWriter@2a5ca609
) 是相同的。它们还生成相同的 JSON
有效负载。
因此,我们使用 ObjectMapper
的第一个实例创建并配置了 ObjectWriter
。但主要只用到最后一个。中间的都已经走了,等待 GC
收集。这样做是没有意义的。最好创建 ObjectMapper
实例,配置它并创建 ObjectWriter
已经通过调用 writer()
方法配置。您可以为 ObjectMapper
的已配置实例创建类似 Factory
的 class,并且您可以使用这些实例生成 ObjectWriter
-s.
com.fasterxml.jackson.databind.ObjectMapper JavaDocs 说:
Mapper instances are fully thread-safe provided that ALL configuration of the instance occurs before ANY read or write calls. If configuration of a mapper instance is modified after first usage, changes may or may not take effect, and configuration calls themselves may fail. If you need to use different configuration, you have two main possibilities:
Construct and use ObjectReader for reading, ObjectWriter for writing. Both types are fully immutable and you can freely create new instances with different configuration using either factory methods of ObjectMapper, or readers/writers themselves. Construction of new ObjectReaders and ObjectWriters is a very light-weight operation so it is usually appropriate to create these on per-call basis, as needed, for configuring things like optional indentation of 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?
就像文档说的那样,这是非常便宜的操作,您可以做到 "on per call basis"。让我们看看每种方法背后都有什么。
ObjectMapper.writer
- 使用来自ObjectMapper
. 的 ObjectWriter.with
- 创建基于caller
实例的新ObjectWriter
以及必须启用的新功能。如果已启用给定功能,则返回相同的实例。如果功能更改配置 - 创建并返回新ObjectWriter
。
SerializationConfig
创建新的 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));
}
}
以上应用打印:
com.fasterxml.jackson.databind.ObjectWriter@2ed94a8b = {"key":123}
com.fasterxml.jackson.databind.ObjectWriter@2a5ca609 = {
"key" : 123
}
com.fasterxml.jackson.databind.ObjectWriter@2a5ca609 = {
"key" : 123
}
com.fasterxml.jackson.databind.ObjectWriter@20e2cbe0 = {
"key" : "123"
}
com.fasterxml.jackson.databind.ObjectWriter@68be2bc2 = {
"key" : "123"
}
注意,第二个 (writer1
) 和第三个 (writer2
) 个实例 (com.fasterxml.jackson.databind.ObjectWriter@2a5ca609
) 是相同的。它们还生成相同的 JSON
有效负载。
因此,我们使用 ObjectMapper
的第一个实例创建并配置了 ObjectWriter
。但主要只用到最后一个。中间的都已经走了,等待 GC
收集。这样做是没有意义的。最好创建 ObjectMapper
实例,配置它并创建 ObjectWriter
已经通过调用 writer()
方法配置。您可以为 ObjectMapper
的已配置实例创建类似 Factory
的 class,并且您可以使用这些实例生成 ObjectWriter
-s.