当前位置: 首页 > 知识库问答 >
问题:

@JsonSerialize(使用=MyCustomSerializer.class)未按预期工作

王弘和
2023-03-14

我有一个应用程序实体,其中包含一些参数,如CustomerName、Address和CardNumber。在用Jackson将其序列化为JSON时,我希望卡号被屏蔽。例如,如果CardNumber为1234567890134,我希望JSON的值为CardNumber:1234*******1234。所以我在Card Number属性上添加了@JsonSerialize注释,并使其使用我的自定义序列化器类。但这似乎不起作用。

实体类

  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;
       }

   }

自定义序列化程序类

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);
    }

}

Marshaller类

 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。写入(应用),未调用自定义序列化程序。所以我没有得到预期的输出。有人能帮忙吗?

共有1个答案

巴宏恺
2023-03-14

当我发现自己对Jackson注释和JAXB注释感到困惑时,我解决了这个问题@xmlement是jaxb,@JsonSerialize是jackson。

我编写了一个定制的jaxb marshaller amd解决了这个问题。

 类似资料:
  • 我正在使用spring Roo并希望访问Controller类中的一个bean,该类在ApplicationContext.xml中具有以下配置: 配置类本身是: 在我的Controller中,我认为一个简单的Autowired注释应该可以完成这项工作 在启动过程中,spring在setSkipWeeks方法中打印消息。不幸的是,每当我在控制器中调用config.getSkipWeeks()时,它

  • 当我运行以下程序时,它只打印 然而,从Java 8的equalsIgnoreCase文档中我们发现: 如果以下至少一项为真,则两个字符c1和c2被视为相同的忽略情况: •对每个字符应用java.lang.character.ToUpperCase(char)方法会产生相同的结果 所以我的问题是为什么这个程序不打印 在这两种操作中,都使用了大写字符。

  • 我试图使用来传输我根据前面的问题设置的自定义标头。 我在文件中读到... 我的属性包括:

  • 我正在和selenium一起工作,刮一些数据。 有一个按钮在页面上,我正在点击说“Custom_Cols”。这个按钮为我打开了一个窗口,我可以在那里选择我的列。 我的问题是为什么新窗口上的元素不可见,即使我正在等待元素的可见。补充一下,我已经尝试增加延迟时间,但我还是会偶尔出现这个错误。 我的密码在这里

  • 我正在使用Grails 2.0.1中的springsecurity插件。我的角色层次结构和其他s2属性如下所示。