jef*_*eon 18 java serialization jackson
我知道如何在Jackson中使用自定义序列化程序(通过扩展JsonSerializer),但我希望默认的序列化程序适用于所有字段,除了1个字段,我想使用自定义序列化程序覆盖它.
注释不是一个选项,因为我正在序列化生成的类(来自Thrift).
在编写自定义jackson序列化程序时,如何仅指定要覆盖的某些字段?
更新:
这是我要序列化的类:
class Student {
int age;
String firstName;
String lastName;
double average;
int numSubjects
// .. more such properties ...
}
Run Code Online (Sandbox Code Playgroud)
上面的类有许多特性,其中大多数使用本机类型.我想覆盖自定义序列化程序中的一些属性,让Jackson像往常一样处理其余的属性.例如,我只想将"年龄"字段转换为自定义输出.
Aru*_*hny 13
假设您的Target类是
public class Student {
int age;
String firstName;
String lastName;
double average;
int numSubjects;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public double getAverage() {
return average;
}
public void setAverage(double average) {
this.average = average;
}
public int getNumSubjects() {
return numSubjects;
}
public void setNumSubjects(int numSubjects) {
this.numSubjects = numSubjects;
}
}
Run Code Online (Sandbox Code Playgroud)
您需要编写自定义序列化程序,如下所示
public class MyCustomSerializer extends JsonSerializer<Student> {
@Override
public void serialize(Student value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
if (value != null) {
jgen.writeStartObject();
jgen.writeStringField("age", "Age: " + value.getAge()); //Here a custom way to render age field is used
jgen.writeStringField("firstName", value.getFirstName());
jgen.writeStringField("lastName", value.getLastName());
jgen.writeNumberField("average", value.getAverage());
jgen.writeNumberField("numSubjects", value.getNumSubjects());
//Write other properties
jgen.writeEndObject();
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后将其添加到ObjectMapper
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("custom",
Version.unknownVersion());
module.addSerializer(Student.class, new MyCustomSerializer());
mapper.registerModule(module);
Run Code Online (Sandbox Code Playgroud)
那就像使用它一样
Student s = new Student();
s.setAge(2);
s.setAverage(3.4);
s.setFirstName("first");
s.setLastName("last");
s.setNumSubjects(3);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, s);
System.out.println(sw.toString());
Run Code Online (Sandbox Code Playgroud)
它会产生ao/p之类的东西
{"age":"年龄:2","firstName":"first","lastName":"last","average":3.4,"numSubjects":3}
我遇到了同样的问题,我用CustomSerializerFactory解决了它.
此方法允许您忽略所有对象或特定类型的某些特定字段.
public class EntityCustomSerializationFactory extends CustomSerializerFactory {
//ignored fields
private static final Set<String> IGNORED_FIELDS = new HashSet<String>(
Arrays.asList(
"class",
"value",
"some"
)
);
public EntityCustomSerializationFactory() {
super();
}
public EntityCustomSerializationFactory(Config config) {
super(config);
}
@Override
protected void processViews(SerializationConfig config, BeanSerializerBuilder builder) {
super.processViews(config, builder);
//ignore fields only for concrete class
//note, that you can avoid or change this check
if (builder.getBeanDescription().getBeanClass().equals(Entity.class)){
//get original writer
List<BeanPropertyWriter> originalWriters = builder.getProperties();
//create actual writers
List<BeanPropertyWriter> writers = new ArrayList<BeanPropertyWriter>();
for (BeanPropertyWriter writer: originalWriters){
String propName = writer.getName();
//if it isn't ignored field, add to actual writers list
if (!IGNORED_FIELDS.contains(propName)){
writers.add(writer);
}
}
builder.setProperties(writers);
}
}
}
Run Code Online (Sandbox Code Playgroud)
之后您可以使用以下内容:
objectMapper.setSerializerFactory(new EntityCustomSerializationFactory());
objectMapper.writeValueAsString(new Entity());//response will be without ignored fields
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18726 次 |
| 最近记录: |