使用Univocity解析器验证解析的字段

时间:2018-09-20 22:02:59

标签: univocity

我想知道在使用CsvRoutines软件包时是否可以检查和验证字段。基本上,如果第一列只有数字,我想处理一行,否则跳过/可能抛出异常。我猜2.7.0中发布的@Validate批注可以用于实现此目的。但是我想知道是否还有其他方法可以像2.5.9那样使用较早的版本?

1 个答案:

答案 0 :(得分:2)

此处是库的作者。除了更新到最新版本,别无其他方法。有什么特别的原因为什么您不能升级?

更新:您可以在类的getter或setter上放置@Parsed批注,并在其中进行验证。那可能是最干净的方法了。例如:

class Test {

    private Integer number;

    //accepts a String here... so this is straight from the parser before it tries to convert anything into an integer - which lets you validate or throw a custom exception
    @Parsed
    void setNumber(String number){
        try{
            this.number = Integer.valueOf(number);
        } catch(NumberFormatException e){
            throw new IllegalArgumentException(number + " is not a valid integer");
        }
    }

}

另一种替代方法是使用自定义转换类。复制最新版本中使用的类ValidatedConversion的代码,然后创建如下子类:

public static class RangeLimiter extends ValidatedConversion {
    int min;
    int max;

    public RangeLimiter(String[] args) {
        super(false, false); //not null, not blank
        min = Integer.parseInt(args[0]);
        max = Integer.parseInt(args[1]);
    }

    protected void validate(Object value) {
        super.validate(value); //runs the existing validations for not null and not blank
        int v = ((Number) value).intValue();
        if (v < min || v > max) {
            throw new DataValidationException("out of range: " + min + " >= " + value + " <=" + max);
        }
    }
}

现在在您的代码上,使用此:

@Parsed(field = "number")
@Convert(conversionClass = RangeLimiter.class, args = {"1", "10"}) //min = 1, max = 10
public int number;

我没有针对旧版本进行测试。我认为您可能需要在applyDefaultConversion=false批注中设置标志@Parsed,并使您的转换类将String转换为int,以运行验证。

总而言之,只需升级到最新版本就可以轻松避免很多工作。