带有转换器的Xstream字段即使使用@XStreamAsAttribute也不是属性

时间:2015-01-16 14:24:15

标签: java xml xstream

我尝试编组一个对象,并希望所有字段都是属性。 @XStreamAsAttribute注释的正常字段是正常的,但我有两个带转换器。对于他们,当我编组时,他们被转换为场地......

@XStreamAlias(value="sinistre")
public class ObjetMetierSinistreDto {

    @XStreamAlias(value="S_sinistreEtat")
    @XStreamAsAttribute
    private String etat;

    @XStreamAsAttribute
    @XStreamAlias(value="S_sinistreDateSurv")
    @XStreamConverter(value=JodaDateConverter.class)
    private LocalDate dateSurvenanceDossier;
...

转换器:

public class JodaDateConverter implements Converter {

@Override
@SuppressWarnings("unchecked")
public boolean canConvert(final Class type) {
      return (type != null) && LocalDate.class.getPackage().equals(type.getPackage());
}

@Override
public void marshal(final Object source, final HierarchicalStreamWriter writer,
      final MarshallingContext context) {
      writer.setValue(source.toString().replace("-", "/"));
}

@Override
@SuppressWarnings("unchecked")
public Object unmarshal(final HierarchicalStreamReader reader,
      final UnmarshallingContext context) {
      try {
              final Class requiredType = context.getRequiredType();
              final Constructor constructor = requiredType.getConstructor(Object.class);
              return constructor.newInstance(reader.getValue());
      } catch (final Exception e) {
          throw new RuntimeException(String.format(
           "Exception while deserializing a Joda Time object: %s", context.getRequiredType().getSimpleName()), e);
      }
}

}

结果:

<sinistre S_sinistreEtat="S">        
  <S_sinistreDateSurv>2015/02/01</S_sinistreDateSurv>
</sinistre>

和我喜欢的:

<sinistre S_sinistreEtat="S"
          S_sinistreDateSurv="2015/02/01"/>

1 个答案:

答案 0 :(得分:0)

我终于找到了解决这个问题的方法!

JodaDateConverter不应该实现Converter,而是扩展AbstractSingleValueConverter(作为来自XStream的DateConverter)

然后你只需要覆盖canConvert()fromString(),你就可以了!

例:

public class JodaDateConverter extends AbstractSingleValueConverter {



 @Override
  @SuppressWarnings("unchecked")
  public boolean canConvert(final Class type) {
          return (type != null) && LocalDate.class.getPackage().equals(type.getPackage());
  }

  @Override
  public Object fromString(String str) {
    String separator;
    if(str.contains(":")){
      separator = ":";
    } else if(str.contains("/")){
      separator = "/";
    } else if(str.contains("-")){
      separator = "-";
    } else {
      throw new RuntimeException("The date must contains ':' or '/' or '-'");
    }
    String[] date = str.split(separator);
    if(date.length < 3){
      throw new RuntimeException("The date must contains hour, minute and second");
    }
    return new LocalDate(Integer.valueOf(date[0]),Integer.valueOf(date[1]),Integer.valueOf(date[2]));
  }

}