@JsonSerialize(using = MyCustomSerializer.class 没有按预期工作
@JsonSerialize(using = MyCustomSerializer.class is not working as expected
我有一个 App 实体,其中包含一些参数,例如 CustomerName、Address 和 CardNumber。在使用 Jackson 将其序列化为 JSON 时,我希望屏蔽卡号。例如,如果 CardNumber 是 12345678901234,我希望 JSON 的值为 CardNumber:1234******1234。因此,我在卡号 属性 上添加了 @JsonSerialize 注释,并使其使用我的自定义序列化程序 class。但这似乎不起作用。
实体Class
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "TransactionDetailsType", propOrder = { "CustomerName", "Address", "CardNumber" })
public class App {
@XmlElement(name = "Address")
private String address;
@JsonSerialize(using = CardNumberMaskingSerializer.class)
@XmlElement(name = "CardNumber")
private String cardNumber;
@XmlElement(name = "CustomerName")
private String customerName;
public String getAddress() {
return address;
}
public String getCardNumber() {
return cardNumber;
}
public String getCustomerName() {
return customerName;
}
public void setAddress(String address) {
this.address = address;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
自定义序列化器Class
public class CardNumberMaskingSerializer extends JsonSerializer<String> {
private final static String MASK_CHAR = "*";
@Override
public void serialize(String cardNumber, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonProcessingException {
String s = cardNumber.replaceAll("\D", "");
System.out.println(s);
int start = 4;
int end = s.length() - 4;
String overlay = StringUtils.repeat(MASK_CHAR, end - start);
String maskedNumber = StringUtils.overlay(s, overlay, start, end);
System.out.println(maskedNumber);
jgen.writeString(maskedNumber);
}
}
编组器Class
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
public class AppMarshaller {
private final ObjectMapper mapper;
public AppMarshaller() {
mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
mapper.setDeserializationConfig(mapper.getDeserializationConfig().withAnnotation Introspector(introspector));
mapper.setSerializationConfig(mapper.getSerializationConfig().withAnnotationIntr ospector(introspector));
}
public App read(String jsonText) {
try {
return mapper.readValue(jsonText, App.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public String write(App details) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
mapper.setSerializationConfig(mapper.getSerializationConfig().withAnnotationIntrospector(
new JaxbAnnotationIntrospector()));
mapper.writeValue(byteStream, details);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
return byteStream.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
但是当我尝试在 JUNIT 中测试它时,通过调用 marshaller.write(app),自定义序列化器没有被调用。所以我没有得到预期的输出。有人可以帮忙吗?
当我发现自己混淆了 Jackson 注释和 JAXB 注释时,我解决了这个问题。 @XmlElement 是 jaxb,@JsonSerialize 是 jackson。
我写了一个自定义的 jaxb 编组器并解决了这个问题。
我有一个 App 实体,其中包含一些参数,例如 CustomerName、Address 和 CardNumber。在使用 Jackson 将其序列化为 JSON 时,我希望屏蔽卡号。例如,如果 CardNumber 是 12345678901234,我希望 JSON 的值为 CardNumber:1234******1234。因此,我在卡号 属性 上添加了 @JsonSerialize 注释,并使其使用我的自定义序列化程序 class。但这似乎不起作用。
实体Class
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "TransactionDetailsType", propOrder = { "CustomerName", "Address", "CardNumber" })
public class App {
@XmlElement(name = "Address")
private String address;
@JsonSerialize(using = CardNumberMaskingSerializer.class)
@XmlElement(name = "CardNumber")
private String cardNumber;
@XmlElement(name = "CustomerName")
private String customerName;
public String getAddress() {
return address;
}
public String getCardNumber() {
return cardNumber;
}
public String getCustomerName() {
return customerName;
}
public void setAddress(String address) {
this.address = address;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
自定义序列化器Class
public class CardNumberMaskingSerializer extends JsonSerializer<String> {
private final static String MASK_CHAR = "*";
@Override
public void serialize(String cardNumber, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonProcessingException {
String s = cardNumber.replaceAll("\D", "");
System.out.println(s);
int start = 4;
int end = s.length() - 4;
String overlay = StringUtils.repeat(MASK_CHAR, end - start);
String maskedNumber = StringUtils.overlay(s, overlay, start, end);
System.out.println(maskedNumber);
jgen.writeString(maskedNumber);
}
}
编组器Class
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
public class AppMarshaller {
private final ObjectMapper mapper;
public AppMarshaller() {
mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
mapper.setDeserializationConfig(mapper.getDeserializationConfig().withAnnotation Introspector(introspector));
mapper.setSerializationConfig(mapper.getSerializationConfig().withAnnotationIntr ospector(introspector));
}
public App read(String jsonText) {
try {
return mapper.readValue(jsonText, App.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public String write(App details) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
mapper.setSerializationConfig(mapper.getSerializationConfig().withAnnotationIntrospector(
new JaxbAnnotationIntrospector()));
mapper.writeValue(byteStream, details);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
return byteStream.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
但是当我尝试在 JUNIT 中测试它时,通过调用 marshaller.write(app),自定义序列化器没有被调用。所以我没有得到预期的输出。有人可以帮忙吗?
当我发现自己混淆了 Jackson 注释和 JAXB 注释时,我解决了这个问题。 @XmlElement 是 jaxb,@JsonSerialize 是 jackson。
我写了一个自定义的 jaxb 编组器并解决了这个问题。