在多个 Jackson 映射器之间创建唯一配置
Create Unique Configuration between multiple Jackson mappers
Jackson
中是否有任何接口,或为多个对象映射器创建相同配置的更好方法?
例如,我有这两种方法用于相同的 class:
public static File toCsv(List<Entity> entityList) {
final File tempFile = new File(CSV_FILE_NAME);
tempFile.deleteOnExit();
CsvMapper mapper = new CsvMapper();
mapper.findAndRegisterModules()
.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true)
.addMixIn(Entity.class, EntityMixIn.class)
.addMixIn(EntityB.class, EntityBMixIn.class);
CsvSchema schema = mapper.schemaFor(Entity.class).withHeader();
try {
mapper.writer(schema).writeValue(tempFile,entityList);
return tempFile;
} catch (IOException ex) {
throw new Exception();
}
}
}
public static File toXml(List<Entity> entityList) {
final File tempFile = new File(XML_FILE_NAME);
tempFile.deleteOnExit();
XmlMapper mapper = new XmlMapper();
mapper.findAndRegisterModules()
.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true)
.addMixIn(Entity.class, EntityMixIn.class)
.addMixIn(EntityB.class, EntityBMixIn.class);
try {
mapper.writeValue(tempFile, entityList);
return tempFile;
} catch (IOException ex) {
throw new Exception();
}
}
}
并且两者的配置完全相同,如果将来我需要一种新格式,我可能会使用相同的配置。
要定义 MixIn
和自定义 serialisers/deserialisers,您可以使用 SimpleModule
。对于 ObjectMapper
上的 enabling/disabling 个功能,您可以创建一个方法。
class MapperFactory {
private final ObjectMapper jsonMapper = configure(new ObjectMapper());
private final XmlMapper xmlMapper = configure(new XmlMapper());
private final CsvMapper csvMapper = configure(new CsvMapper());
public ObjectMapper getJsonMapper() {
return jsonMapper;
}
public XmlMapper getXmlMapper() {
return xmlMapper;
}
public CsvMapper getCsvMapper() {
return csvMapper;
}
public <T extends ObjectMapper> T configure(T mapper) {
// configure mapper instance if required
mapper.enable(JsonGenerator.Feature.IGNORE_UNKNOWN);
// register default
mapper.findAndRegisterModules();
// register custom
mapper.registerModule(createCustomModule());
return mapper;
}
public SimpleModule createCustomModule() {
SimpleModule module = new SimpleModule("EntityMixIns");
module.setMixInAnnotation(Entity.class, EntityMixIn.class);
// more MixIns
return module;
}
}
简单用法:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class JsonApp {
public static void main(String[] args) throws Exception {
MapperFactory mapperFactory = new MapperFactory();
System.out.println("JSON:");
System.out.println(mapperFactory.getJsonMapper().writeValueAsString(new Entity()));
System.out.println("XML:");
System.out.println(mapperFactory.getXmlMapper().writeValueAsString(new Entity()));
System.out.println("CSV:");
CsvMapper csvMapper = mapperFactory.getCsvMapper();
CsvSchema schema = csvMapper.schemaFor(Entity.class).withHeader();
System.out.println(csvMapper.writer(schema).writeValueAsString(new Entity()));
}
}
class Entity {
private int id = 12;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "A{" + "id=" + id + '}';
}
}
interface EntityMixIn {
@JsonProperty("_idName")
int getId();
}
以上代码打印:
JSON:
{"_idName":12}
XML:
<Entity><_idName>12</_idName></Entity>
CSV:
_idName
12
另请参阅:
- Should I declare Jackson's ObjectMapper as a static field?
- How do I correctly reuse Jackson ObjectMapper?
Jackson
中是否有任何接口,或为多个对象映射器创建相同配置的更好方法?
例如,我有这两种方法用于相同的 class:
public static File toCsv(List<Entity> entityList) {
final File tempFile = new File(CSV_FILE_NAME);
tempFile.deleteOnExit();
CsvMapper mapper = new CsvMapper();
mapper.findAndRegisterModules()
.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true)
.addMixIn(Entity.class, EntityMixIn.class)
.addMixIn(EntityB.class, EntityBMixIn.class);
CsvSchema schema = mapper.schemaFor(Entity.class).withHeader();
try {
mapper.writer(schema).writeValue(tempFile,entityList);
return tempFile;
} catch (IOException ex) {
throw new Exception();
}
}
}
public static File toXml(List<Entity> entityList) {
final File tempFile = new File(XML_FILE_NAME);
tempFile.deleteOnExit();
XmlMapper mapper = new XmlMapper();
mapper.findAndRegisterModules()
.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true)
.addMixIn(Entity.class, EntityMixIn.class)
.addMixIn(EntityB.class, EntityBMixIn.class);
try {
mapper.writeValue(tempFile, entityList);
return tempFile;
} catch (IOException ex) {
throw new Exception();
}
}
}
并且两者的配置完全相同,如果将来我需要一种新格式,我可能会使用相同的配置。
要定义 MixIn
和自定义 serialisers/deserialisers,您可以使用 SimpleModule
。对于 ObjectMapper
上的 enabling/disabling 个功能,您可以创建一个方法。
class MapperFactory {
private final ObjectMapper jsonMapper = configure(new ObjectMapper());
private final XmlMapper xmlMapper = configure(new XmlMapper());
private final CsvMapper csvMapper = configure(new CsvMapper());
public ObjectMapper getJsonMapper() {
return jsonMapper;
}
public XmlMapper getXmlMapper() {
return xmlMapper;
}
public CsvMapper getCsvMapper() {
return csvMapper;
}
public <T extends ObjectMapper> T configure(T mapper) {
// configure mapper instance if required
mapper.enable(JsonGenerator.Feature.IGNORE_UNKNOWN);
// register default
mapper.findAndRegisterModules();
// register custom
mapper.registerModule(createCustomModule());
return mapper;
}
public SimpleModule createCustomModule() {
SimpleModule module = new SimpleModule("EntityMixIns");
module.setMixInAnnotation(Entity.class, EntityMixIn.class);
// more MixIns
return module;
}
}
简单用法:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class JsonApp {
public static void main(String[] args) throws Exception {
MapperFactory mapperFactory = new MapperFactory();
System.out.println("JSON:");
System.out.println(mapperFactory.getJsonMapper().writeValueAsString(new Entity()));
System.out.println("XML:");
System.out.println(mapperFactory.getXmlMapper().writeValueAsString(new Entity()));
System.out.println("CSV:");
CsvMapper csvMapper = mapperFactory.getCsvMapper();
CsvSchema schema = csvMapper.schemaFor(Entity.class).withHeader();
System.out.println(csvMapper.writer(schema).writeValueAsString(new Entity()));
}
}
class Entity {
private int id = 12;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "A{" + "id=" + id + '}';
}
}
interface EntityMixIn {
@JsonProperty("_idName")
int getId();
}
以上代码打印:
JSON:
{"_idName":12}
XML:
<Entity><_idName>12</_idName></Entity>
CSV:
_idName
12
另请参阅:
- Should I declare Jackson's ObjectMapper as a static field?
- How do I correctly reuse Jackson ObjectMapper?