興味のある方は、JsonHierarchicalStreamDriver は JsonWriter というクラスを使っているようです。それらの間で、Double、Integer などはすべて 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 は、double 値と小数点以下の桁数という 2 つのプロパティを持つクラスです。
私が言うように、これはハックであり (非常に壊れやすく、私が気付いていない多くの問題を抱えている可能性があります)、その方法を考え出すときにおそらく法律を破りました。私はおそらくそれを使用することさえありませんが、それは私の元の質問に答えます.