如果有人感兴趣,似乎 JsonHierarchicalStreamDriver 使用了一个名为 JsonWriter 的类。在它们之间,他们假设任何双精度数、整数等转换为 JSON 数字,而自定义对象将被转换为文本(即用引号括起来)。似乎无论如何都没有指定您希望如何呈现值。
如果您仍然需要完成,有几种选择。您也许可以使用 JsonHierarchicalStreamDriver 的替代方案。该文档暗示 JettisonMappedXmlDriver 的一个版本会将所有类似数字的字符串转换为 JSON 数字(并不总是需要)。
我使用了以下肮脏的技巧:
创建一个允许您删除引号的新作者:
public static class HackJsonWriter extends JsonWriter {
public HackJsonWriter(Writer writer) {
super(writer);
}
private boolean dropQuotes = false;
public void dropQuotes() {
dropQuotes = true;
}
public void allowQuotes() {
dropQuotes = false;
}
@Override
protected void addValue(String value, AbstractJsonWriter.Type type)
{
if (dropQuotes) {
super.addValue(value, AbstractJsonWriter.Type.NULL);
}
else {
super.addValue(value, type);
}
}
}
通过以下方式覆盖编写器的创建:
new XStream(new JsonHierarchicalStreamDriver() {
@Override
public HierarchicalStreamWriter createWriter(Writer writer) {
return new HackJsonWriter(writer);
}
});
创建一个发现黑客并处理它的转换器。
public static class HackRoundedDoubleConverter implements Converter {
private HackRoundedDoubleConverter() {
}
@Override
public boolean canConvert(Class clazz) {
return RoundedDouble.class.isAssignableFrom(clazz);
}
@Override
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
if (value == null) {
return; // now that i think about it, this should probably write "null" (no quotes), but I was handling that elsewhere
}
RoundedDouble number = (RoundedDouble)value;
if (Double.isNaN(number.getValue()) || Double.isInfinite(number.getValue())) {
return; // at this point, we would have a problem. an empty node will be created no matter what (and it translates to an empty object in javascript).
}
if (writer.underlyingWriter() instanceof HackJsonWriter) {
HackJsonWriter hackWriter = (HackJsonWriter)writer.underlyingWriter();
hackWriter.dropQuotes();
writer.setValue(number.getRoundedValue());
hackWriter.allowQuotes();
}
else {
writer.setValue(number.getRoundedValue());
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
// only interested in the one direction
return null;
}
}
注册转换器:
xstream.registerConverter(new HackRoundedDoubleConverter());
RoundedDouble 是一个具有两个属性、一个双精度值和多个小数位的类。
正如我所说,它是一种 hack(它非常脆弱,可能有很多我什至没有发现的问题),而且我可能在研究如何做时触犯了法律。我可能什至不会使用它,但它回答了我最初的问题。