【问题标题】:Validate each filed against multiple constraints using CSV Parser使用 CSV Parser 针对多个约束验证每个文件
【发布时间】:2015-12-20 09:03:36
【问题描述】:

我正在处理需要针对多个验证解析 CSV 记录字段的要求。我正在使用支持字段级处理器验证数据的 supercsv。

我的要求是针对多个验证验证每个记录/行字段,并将它们以成功/失败状态保存到数据库中。对于失败记录,我必须使用一些代码显示所有失败的验证。

Super CSV 是工作文件,但它只检查文件的第一次验证,如果失败,则忽略同一字段的第二次验证。请查看下面的代码并帮助我。

package com.demo.supercsv;

import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.StrRegEx;
import org.supercsv.cellprocessor.constraint.UniqueHashCode;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCsvCellProcessorException;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

public class ParserDemo {

    public static void main(String[] args) throws IOException {

        List<Employee> emps = readCSVToBean();
        System.out.println(emps);
        System.out.println("******");
        writeCSVData(emps);
    }

    private static void writeCSVData(List<Employee> emps) throws IOException {
        ICsvBeanWriter beanWriter = null;
        StringWriter writer = new StringWriter();
        try{
            beanWriter = new CsvBeanWriter(writer, CsvPreference.STANDARD_PREFERENCE);
            final String[] header = new String[]{"id","name","role","salary"};
            final CellProcessor[] processors = getProcessors();

            // write the header
            beanWriter.writeHeader(header);

            //write the beans data
            for(Employee emp : emps){
                beanWriter.write(emp, header, processors);
            }
        }finally{
            if( beanWriter != null ) {
                beanWriter.close();
            }
        }
        System.out.println("CSV Data\n"+writer.toString());
    }

    private static List<Employee> readCSVToBean() throws IOException {
        ICsvBeanReader beanReader = null;
        List<Employee> emps = new ArrayList<Employee>();
        try {
            beanReader = new CsvBeanReader(new FileReader("src/employees.csv"),
                    CsvPreference.STANDARD_PREFERENCE);

            // the name mapping provide the basis for bean setters 
            final String[] nameMapping = new String[]{"id","name","role","salary"};
            //just read the header, so that it don't get mapped to Employee object
            final String[] header = beanReader.getHeader(true);
            final CellProcessor[] processors = getProcessors();

            Employee emp;

            while ((emp = beanReader.read(Employee.class, nameMapping,
                    processors)) != null) {
                emps.add(emp);


                if (!CaptureExceptions.SUPPRESSED_EXCEPTIONS.isEmpty()) {
                    System.out.println("Suppressed exceptions for row "
                                        + beanReader.getRowNumber() + ":");
                    for (SuperCsvCellProcessorException e :
                        CaptureExceptions.SUPPRESSED_EXCEPTIONS) {
                        System.out.println(e);
                    }
                    // for processing next row clearing validation list
                    CaptureExceptions.SUPPRESSED_EXCEPTIONS.clear();
                }

            }

        } finally {
            if (beanReader != null) {
                beanReader.close();
            }
        }
        return emps;
    }

    private static CellProcessor[] getProcessors() {

        final CellProcessor[] processors = new CellProcessor[] { 

                new CaptureExceptions(new NotNull(new StrRegEx("\\d+",new StrMinMax(0, 2)))),//id must be in digits and should not be more than two charecters
                new CaptureExceptions(new Optional()), 
                new CaptureExceptions(new Optional()), 
                new CaptureExceptions(new NotNull()), 
                 // Salary
        };
        return processors;
    }

}

异常处理程序:

package com.demo.supercsv;

import java.util.ArrayList;
import java.util.List;
import org.supercsv.cellprocessor.CellProcessorAdaptor;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCsvCellProcessorException;
import org.supercsv.util.CsvContext;

public class CaptureExceptions extends CellProcessorAdaptor {

    public static List<SuperCsvCellProcessorException> SUPPRESSED_EXCEPTIONS = 
            new ArrayList<SuperCsvCellProcessorException>();

    public CaptureExceptions(CellProcessor next) {
        super(next);
    }

    public Object execute(Object value, CsvContext context) {
        try {
            return next.execute(value, context);

        } catch (SuperCsvCellProcessorException e) {
            // save the exception
            SUPPRESSED_EXCEPTIONS.add(e);
            if(value!=null)
                return value.toString();
                else
                    return "";
        }
    }
}

示例 csv 文件

ID,Name,Role,Salary
a123,kiran,CEO,"5000USD"
2,Kumar,Manager,2000USD
3,David,developer,1000USD

当我运行我的程序 supercsv 异常处理程序时,在第一行中显示此 ID 值的消息

Suppressed exceptions for row 2:
org.supercsv.exception.SuperCsvConstraintViolationException: 'a123' does not match the regular expression '\d+'
processor=org.supercsv.cellprocessor.constraint.StrRegEx
context={lineNo=2, rowNo=2, columnNo=1, rowSource=[a123, kiran, CEO, 5000USD]}
[com.demo.supercsv.Employee@23bf011e, com.demo.supercsv.Employee@50e26ae7, com.demo.supercsv.Employee@40d88d2d]

字段 ID 长度不应为 null 且不应超过两个,并且应为数字...我已经定义了这样的字段处理器。

new CaptureExceptions(new NotNull(new StrRegEx("\\d+",new StrMinMax(0, 2))))

但是如果给定的输入不是数字,则超级 csv 会忽略第二次验证(maxlenght 2)...如果我的输入是 100,那么它的验证最大长度是 ..但是如何为错误的输入获得两个验证。请帮助我

【问题讨论】:

    标签: java csv supercsv


    【解决方案1】:

    SuperCSV 单元处理器将按顺序工作。因此,如果它通过了上一个约束验证,那么它将检查下一个。

    为了实现你的目标,你需要编写一个自定义的 CellProcessor,它会检查输入是否为数字(数字),长度是否在 0 到 2 之间。 因此,这两项检查都在一个步骤中完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      相关资源
      最近更新 更多