【问题标题】:Retrofit SimpleXMLConverter NumberFormatException on empty attribute在空属性上改造 SimpleXMLConverter NumberFormatException
【发布时间】:2014-07-09 16:57:28
【问题描述】:

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

我尝试过使用

@Attribute(empty="-1")

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

【问题讨论】:

    标签: android string square simple-framework retrofit


    【解决方案1】:

    如果属性有时不是“”,也就是空的,它会正常工作。

    这里不正确:属性值 - 被视为字符串 - 不是 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,则不会捕获异常,值将设置为空字符串 ("")。另一方面,保留字符串类型但删除 XML 中的属性会将"-1" 设置为值(这就是使用required = false 的原因)。现在序列化器找不到任何值,因此设置了默认值。

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

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

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

    但有一个更好的解决方案:Simple 允许您为任何类型实现自定义Transformer(不要与Converter!)。有了这些,您可以根据需要实现 type -&gt; String(写入)String -&gt; 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}
    

    【讨论】:

    • 如果是test 你会得到“test”字符串吗?
    • 您可以使用@Text;有关示例,请参见 here
    【解决方案2】:

    @vandus,这是我到目前为止所做的: 我在Main onCreate类中创建了一个适配器,我作为List传入的Model是XML文件的根节点:http://www.w3schools.com//xml/simple.xml

          RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint("http://www.w3schools.com")
                    .setConverter(new SimpleXMLConverter())
                    .build();
    
                GitHubService foodService = restAdapter.create(GitHubService.class);
                List<BreakfastMenu> repos = foodService.getFile();
                repos.toString();
    
    
    
    public interface GitHubService
      {
        @GET("/xml/simple.xml")
        List<BreakfastMenu> getFile();
      }
    

    【讨论】:

    • 能否为您的问题创建一个新的、单独的问题?原始问题与您的问题无关。我会在那里回答你。只需在此处添加评论,说明我在哪里可以找到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2016-09-19
    • 2019-02-15
    • 2013-08-04
    • 2022-01-22
    • 2021-07-18
    • 2013-08-01
    相关资源
    最近更新 更多