在空属性上改进SimpleXMLConverter NumberFormatException

时间:2014-07-09 16:57:29

标签: android string square simple-framework retrofit

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

我尝试使用

@Attribute(empty="-1")

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

2 个答案:

答案 0 :(得分:1)

  

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

这里不正确:属性值 - 看作字符串 - 不是,意思是缺失或“没有”,它是空字符串。< / p>

以下是一个例子:

<强> 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的原因)。现在,Serializer找不到任何值,因此设置了默认值。

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

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

    return Long.valueOf(value);
}

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

但是有一个更好的解决方案:Simple允许您为任何类型实现自定义Transformer (不要与 {{1}混合使用} !)。有了这些,您可以根据需要实现 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);

答案 1 :(得分:0)

@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();
  }