代码之家  ›  专栏  ›  技术社区  ›  user2220232

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

  •  1
  • user2220232  · 技术社区  · 6 年前

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   Jeronimo Backes    6 年前

    这里是图书馆的作者。除了更新到最新版本之外,没有别的办法了。有什么特别的原因不能升级吗?

    @Parsed 类的getter或setter上的注释,并在其中执行验证。这可能是最干净的方法。例如:

    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 @已解析 注释,并使转换类转换为 String 变成一个 int 除了运行验证。

    总而言之,只要升级到最新版本,就可以很容易地避免相当多的工作。