用三种方案实现
private String salary; 与 <Salary Ccy="CNY">20000.00</Salary> 的序列化和反序列化
共用类
适配实体类 CcyAmt.class
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
public class CcyAmt {
@JacksonXmlProperty(isAttribute = true)
private String ccy;
@JacksonXmlText
private Object value;
public CcyAmt() {}
public CcyAmt(String ccy, Object value) {
this.ccy = ccy;
this.value = value;
}
public String getCcy() {
return ccy;
}
public void setCcy(String ccy) {
this.ccy = ccy;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
序列化实现类 CcySerializer.class
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
public class CcySerializer extends JsonSerializer<Object> implements ContextualSerializer {
private String ccyValue;
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
CcyAmt ccyAmt = new CcyAmt(ccyValue, value);
gen.writeObject(ccyAmt);
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
throws JsonMappingException {
Ccy ccy = property.getAnnotation(Ccy.class);
ccyValue = ccy.value();
return this;
}
}
反序列化实现类 CcyDeserializer.class
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class CcyDeserializer extends JsonDeserializer<Object> {
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
CcyAmt ccyAmt = p.readValueAs(CcyAmt.class);
return ccyAmt.getValue();
}
}
1、最简单的实现
Ccy注解 直接指定策略
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@Retention(RUNTIME)
@Target(FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = CcySerializer.class)
@JsonDeserialize(using = CcyDeserializer.class)
public @interface Ccy {
String value() default "CNY";
}
在 Person.class 字段上直接添加Cyy注解
public class Person {
private String name;
private String age;
private String sex;
private String testName;
@Ccy
private String salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", testName=" + testName + ", salary="
+ salary + "]";
}
}
简单使用 XmlMapper
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Test {
public static void main(String[] args) throws IOException {
Person person = new Person();
person.setName("一个人");
person.setAge("18");
person.setSex("1");
person.setSalary("20000.00");
person.setTestName("测试人");
ObjectMapper mapper = new XmlMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);
String value = mapper.writeValueAsString(person);
System.out.println(value);
Person readValue = mapper.readValue(value, Person.class);
System.out.println(readValue);
}
}
打印结果
<Person><Name>一个人</Name><Age>18</Age><Sex>1</Sex><TestName>测试人</TestName><Salary Ccy="CNY">20000.00</Salary></Person>
Person [name=一个人, age=18, sex=1, testName=测试人, salary=20000.00]
2、使用 MixIn 功能
仍然是Ccy注解 直接指定策略
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@Retention(RUNTIME)
@Target(FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = CcySerializer.class)
@JsonDeserialize(using = CcyDeserializer.class)
public @interface Ccy {
String value() default "CNY";
}
未添加注解的 Person.class
public class Person {
private String name;
private String age;
private String sex;
private String testName;
private String salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", testName=" + testName + ", salary="
+ salary + "]";
}
}
CcyMixIn.class 给指定字段混入注解
import com.fasterxml.jackson.annotation.JsonProperty;
public class CcyMixIn {
@Ccy
private String salary;
@JsonProperty("xingbie")
private String sex;
}
使用 XmlMapper 添加混入策略
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Test {
public static void main(String[] args) throws IOException {
Person person = new Person();
person.setName("一个人");
person.setAge("18");
person.setSex("1");
person.setSalary("20000.00");
person.setTestName("测试人");
ObjectMapper mapper = new XmlMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);
mapper.addMixIn(Person.class, CcyMixIn.class);
String value = mapper.writeValueAsString(person);
System.out.println(value);
Person readValue = mapper.readValue(value, Person.class);
System.out.println(readValue);
}
}
打印结果
<Person><Name>一个人</Name><Age>18</Age><TestName>测试人</TestName><Salary Ccy="CNY">20000.00</Salary><xingbie>1</xingbie></Person>
Person [name=一个人, age=18, sex=1, testName=测试人, salary=20000.00]
3、使用 AnnotationIntrospector 功能
仍然是未添加注解的 Person.class
public class Person {
private String name;
private String age;
private String sex;
private String testName;
private String salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", testName=" + testName + ", salary="
+ salary + "]";
}
}
简单的Ccy注解
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(FIELD)
public @interface Ccy {
String value() default "CNY";
}
创建 CcyAnnotationIntrospector 类 指定Ccy注解的策略
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
public class CcyAnnotationIntrospector extends NopAnnotationIntrospector {
private static final long serialVersionUID = -1495356687014456822L;
@Override
public Object findSerializer(Annotated am) {
Ccy annotation = am.getAnnotation(Ccy.class);
if (annotation != null) {
return CcySerializer.class;
}
return null;
}
@Override
public Object findDeserializer(Annotated am) {
Ccy annotation = am.getAnnotation(Ccy.class);
if (annotation != null) {
return CcyDeserializer.class;
}
return null;
}
}
使用 XmlMapper 设置自定义的 CcyAnnotationIntrospector
import java.io.IOException;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Test {
public static void main(String[] args) throws IOException {
Person person = new Person();
person.setName("一个人");
person.setAge("18");
person.setSex("1");
person.setSalary("20000.00");
person.setTestName("测试人");
ObjectMapper mapper = new XmlMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);
AnnotationIntrospector sis = mapper.getSerializationConfig().getAnnotationIntrospector();
AnnotationIntrospector dis = mapper.getDeserializationConfig().getAnnotationIntrospector();
AnnotationIntrospector is1 = AnnotationIntrospectorPair.pair(sis, new CcyAnnotationIntrospector());
AnnotationIntrospector is2 = AnnotationIntrospectorPair.pair(dis, new CcyAnnotationIntrospector());
mapper.setAnnotationIntrospectors(is1, is2);
String value = mapper.writeValueAsString(person);
System.out.println(value);
Person readValue = mapper.readValue(value, Person.class);
System.out.println(readValue);
}
}
打印结果
<Person><Name>一个人</Name><Age>18</Age><Sex>1</Sex><TestName>测试人</TestName><Salary Ccy="CNY">20000.00</Salary></Person>
Person [name=一个人, age=18, sex=1, testName=测试人, salary=20000.00]