Xstream 即使使用@XStreamAsAttribute,带转换器的字段也不是属性
Xstream field with converter is not an attribute even with @XStreamAsAttribute
我尝试编组一个对象,我希望所有字段都是属性。普通字段可以使用@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"/>
我终于找到解决这个问题的方法了!
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]));
}
}
我尝试编组一个对象,我希望所有字段都是属性。普通字段可以使用@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"/>
我终于找到解决这个问题的方法了!
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]));
}
}