Если кому-то интересно, то кажется, что 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 это класс, который имеет два свойства, двойное значение, и количество знаков после запятой.
Как я уже сказал, это хак (он очень хрупок и, вероятно, имеет много проблем, которые я даже не заметил), и я, вероятно, нарушил закон при разработке того, как это сделать. Я, вероятно, даже не буду использовать его, но он отвечает на мой первоначальный вопрос.
быстрый просмотр учебника по конвертерам xstream показывает этот пример: «@XStreamConverter (значение = BooleanConverter.class, booleans = {false}, строки = {« да »,« нет »})». поэтому, похоже, вы можете дать некоторые дополнительные параметры конвертеру. можете ли вы их использовать? –
@DenisTulskiy спасибо, но каждый экземпляр может иметь разное количество знаков после запятой. Если бы был способ передачи текущего объекта или текущего «числа десятичных знаков» в конвертер, это решило бы мою проблему ... – zod
Я думаю, что эта задача намного превосходит то, что могла бы сделать любая библиотека для сортировки. –