Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用XStream和JSONHierarchycalStreamDriver来输出值,如何对double进行舍入?_Java_Xml_Json_Xstream - Fatal编程技术网

Java 使用XStream和JSONHierarchycalStreamDriver来输出值,如何对double进行舍入?

Java 使用XStream和JSONHierarchycalStreamDriver来输出值,如何对double进行舍入?,java,xml,json,xstream,Java,Xml,Json,Xstream,这里有一个类似的问题,正如答案所示,我确实尝试过使用转换器 我正在将对象序列化为xml和json。我在需要时使用XStream和JSONHierarchycalStreamDriver 对象的属性类型为double。这些都很好。在xml中,它序列化为: <value>3.14159265</value> 我现在需要将值四舍五入到给定的小数位数 在我的第一次尝试中,我编写了一个转换器,它将所有的双精度舍入到小数点后2位。这是如上所述呈现的(值被舍入除外),但问题是不同的

这里有一个类似的问题,正如答案所示,我确实尝试过使用转换器

我正在将对象序列化为xml和json。我在需要时使用XStream和JSONHierarchycalStreamDriver

对象的属性类型为double。这些都很好。在xml中,它序列化为:

<value>3.14159265</value>
我现在需要将值四舍五入到给定的小数位数

在我的第一次尝试中,我编写了一个转换器,它将所有的双精度舍入到小数点后2位。这是如上所述呈现的(值被舍入除外),但问题是不同的属性需要舍入到不同的有效数字,并且转换器不知道在“marshal”方法中有多少位小数

我的第二次尝试使用自定义对象替换double,它保存double对象和小数位数。需要另一个转换器,这对xml很有效,但在json中,它将值呈现为字符串(即引号),而不是数字(这是我真正想要的)

如何将四舍五入的双精度体渲染为数字


谢谢

如果有人感兴趣,那么JsonHierarchicalStreamDriver似乎使用了一个名为JsonWriter的类。在它们之间,它们假设任何双精度、整数等转换为JSON数字,而自定义对象将转换为文本(即用引号括起来)。似乎无论如何都没有指定要如何呈现值

如果您仍然需要完成,有几个选项。您可能可以使用JSONHierarchycalStreamDriver的替代方案。该文档表明,一个版本的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(value=BooleanConverter.class,booleans={false},strings={“yes”,“no”})”。因此,您似乎可以为转换器提供一些额外的参数。你能用这些吗?@DenisTulskiy谢谢,但每个实例的小数位数可能不同。如果有一种方法可以将当前对象或当前的“小数位数”传递给转换器,这将解决我的问题……我认为这项任务远远超出了任何编组库的功能。
    xstream.registerConverter(new HackRoundedDoubleConverter());