android - 在空属性上改造 SimpleXMLConverter NumberFormatException

标签 android string square simple-framework retrofit

我正在使用 Retrofit 和 SimpleXMLConverter 来获取和反序列化 XML 文件。我正在将属性转换为 long 类型。如果属性有时是“”,也就是空的,它会很好地工作。

我试过用

@Attribute(empty="-1")

在这种情况下,这个属性应该是空的,所以它应该返回“-1”,但它并没有这样做。这个空属性的用法是否正确?

最佳答案

It would work fine if the attribute wasn´t sometimes "", aka empty.

这里是不正确的:属性值 - 被视为字符串 - 在缺失或“无”的意思上不是,它是一个空字符串

这是一个例子:

XML:

<root value=""></root>

Java 类:

@Root(name = "root")
public class Example
{
    @Attribute(name = "value", empty = "-1", required = false)
    private long value;


    @Override
    public String toString()
    {
        return "Example{" + "value=" + value + '}';
    }
}

这会抛出 - 这是合理的 - NumberFormatException。如果将 value 的类型替换为 String,则不会捕获异常,value 将设置为空字符串 ("")。另一方面,保留字符串类型但删除 XML 中的属性会将 "-1" 设置为值(这就是使用 required = false 的原因)。现在 Serializer 找不到任何值,因此设置默认值。

可以在您的类内部处理这个问题,比如让相应的 getter 方法在空字符串的情况下返回 -1:

public long getValue()
{
    if( value == null || value.isEmpty() == true )
    {
        return -1;
    }

    return Long.valueOf(value);
}

(不要忘记根据此更改代码 - 在我的示例中,您必须更改 toString()-method)

但是有一个更好的解决方案:简单允许您实现自定义Transformer 用于任何类型(不要与 Converter 混合使用!)。有了这些,您就可以实现 type -> String(写入)String -> type(读取)需要。

基于我上面的例子,这里有一个实现:

public class LongTransformer implements Transform<Long>
{
    // Default value which is set if no / empty input is available
    private final long defaultValue;


    public LongTransformer(long defaultValue)
    {
        this.defaultValue = defaultValue;
    }

    public LongTransformer()
    {
        this(-1); // Just in case you always have -1 as default
    }



    @Override
    public Long read(String value) throws Exception
    {
        // If there's no or an empty String the default value is returned
        if( value == null || value.isEmpty() == true )
        {
            return defaultValue; // 
        }

        return Long.valueOf(value); // Return the value
    }


    @Override
    public String write(Long value) throws Exception
    {
        /*
         * Nothing special here. In case you you need a empty string if
         * value = -1, you can do it here.
         */
        return value.toString();
    }
}

最后是一个如何使用的例子。关键部分在两行之间:

final String xml = "<root value=\"\">\n"
                 + "</root>";

// ---------------------------------------------------------------------
final LongTransformer numberTransformer = new LongTransformer(-1);

RegistryMatcher m = new RegistryMatcher();
m.bind(long.class, numberTransformer);

Serializer ser = new Persister(m);
// ---------------------------------------------------------------------

Example root = ser.read(Example.class, xml);
System.out.println(root);

输出:

Example{value=-1}

关于android - 在空属性上改造 SimpleXMLConverter NumberFormatException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24659591/

相关文章:

java - libgdx 中 BoundingBox 和 Sphere 之间的碰撞检测

python - 不支持的格式字符 ";"。想不通

c# - 用双引号将每个单词括起来

c++ - 如何查找和替换字符串中所有出现的子字符串?

android - 统一社交API

android - 无法在 Android 手机上显示 OpenStreetMap

android - React native custom view meet 没有 propType 问题

android - 如何使用 Retrofit 2 处理空响应体?

android - 'offscreen fragments being brought back to life' 和 'no direct control over animations' 是什么意思?

java - 为什么mockito认为我的服务被调用了两次?