解析中的Opencsv自定义逻辑 [英] Opencsv custom logic in parsing

查看:90
本文介绍了解析中的Opencsv自定义逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用openCsv库,因为它非常易于使用,并且我具有所有必需的功能.但是现在我需要使用一些自定义逻辑,除了检查正确的类型,列和其他常见的东西.我有一个列 firstName secondName firstSalary lastSalary 等的csv.我想在解析过程中检查 firstDayOfWork 是否小于 lastDayOfWork ,并在错误的情况下添加一个新的csvException.因此,如果现在我正在对文件进行

I'm using openCsv library cause it's very easy to use and I got all necessary functional. But now I need to use some custom logic except checking for correct types, columns and other usual things. I have a csv with columns firstName, secondName, firstSalary, lastSalary and others. I want to check that firstDayOfWork is less than lastDayOfWork in the process of parcing and add a new csvException if it is false. So, if now I'm parcing file

firstName,secondName,firstSalary,lastSalary
John, Doe, testtext, 5000
Alice, , 100, 5000
Harry, Smith, 400, 200

并处理一个csvExcpetions列表,我可以获得类似

and processing a list of csvExcpetions I can get results of parcing like

Number of mistakes: 2
Line 1: Conversion of testtext to java.lang.Integer failed.
Line 2: Field 'secondName' is mandatory but no value was provided.

我想要类似

Number of mistakes: 3
Line 1: Conversion of testtext to java.lang.Integer failed.
Line 2: Field 'secondName' is mandatory but no value was provided.
Line 3: firstSalary cannot be more than lastSalary

或者一些自定义的比较逻辑,例如检查某个字段是否捕获了regexp,两个字段同时大于0,等等.

Or some custom parcing logic like check if some field catch regexp, two fields at the same time greater than 0, etc.

我可以先将其切碎并将其转换为bean,然后在第二个周期中检查我的bean是否符合这些规则,但是可能会有很多行,并且需要花费更长的时间,因此,我想在一个过程中对其进行检查

I can firstly parce and convert it to beans and by the second cycle check my beans to these rules, but there are can be a lot of lines and it will take longer, so, I want to check it in the one process.

我可以通过openCsv获得它吗?如果是的话,怎么办?如果没有,我可以使用什么其他工具?谢谢.

Can I get it by openCsv? And if yes, how? If no, what another tool I can use? Thank you.

推荐答案

While there is a request on the todo/wish list for OpenCSV I don't think it will help you because it's about pre parsing validation

对于您想要的内容,您应该只在设置器中添加一个检查,以在值不正确时引发异常.这是我的Bean和测试.

For what you want you should just add a check in your setters to throw an exception when the values are bad. Here is my Bean and test.

public class SetterBean {

    @CsvBindByName(column = "First Name", required = true)
    private String firstName;
    @CsvBindByName(column = "Last Name", required = true)
    private String lastName;
    @CsvBindByName(column = "First Salary")
    private Long firstSalary;
    @CsvBindByName(column = "Last Salary")
    private Long lastSalary;

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setFirstSalary(Long firstSalary) {
        if (lastSalary != null && (firstSalary.compareTo(lastSalary) > 0)) {
            throw new IllegalArgumentException("First Salary cannot be greater than Last Salary.");
        }
        this.firstSalary = firstSalary;
    }

    public void setLastSalary(Long lastSalary) {
        if (firstSalary != null && (lastSalary.compareTo(firstSalary) < 0)) {
            throw new IllegalArgumentException("Last Salary cannot be less than First Salary.");
        }
        this.lastSalary = lastSalary;
    }
}

public class SetterValidationTest {
    private static final String HEADER = "First Name,Last Name,First Salary,Last Salary\n";

    CsvToBean<SetterBean> csvToBean;

    @Test
    public void normalData() {
        String data = HEADER + "First, Last, 1, 2";
        csvToBean = new CsvToBeanBuilder<SetterBean>(new StringReader(data))
                .withType(SetterBean.class)
                .build();
        List<SetterBean> beans = csvToBean.parse();
        assertEquals(1, beans.size());
    }

    @Test(expected = Exception.class)
    public void firstGTLast() {
        String data = HEADER + "First, Last, 2, 1";
        csvToBean = new CsvToBeanBuilder<SetterBean>(new StringReader(data))
                .withType(SetterBean.class)
                .build();
        List<SetterBean> beans = csvToBean.parse();
    }
}

这是结果.

Exception in thread "pool-1-thread-1" java.lang.RuntimeException: com.opencsv.exceptions.CsvDataTypeMismatchException
    at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:91)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: com.opencsv.exceptions.CsvDataTypeMismatchException
    at com.opencsv.bean.AbstractBeanField.assignValueToField(AbstractBeanField.java:192)
    at com.opencsv.bean.AbstractBeanField.setFieldValue(AbstractBeanField.java:159)
    at com.opencsv.bean.concurrent.ProcessCsvLine.processField(ProcessCsvLine.java:140)
    at com.opencsv.bean.concurrent.ProcessCsvLine.processLine(ProcessCsvLine.java:126)
    at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:82)
    ... 3 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.opencsv.bean.AbstractBeanField.assignValueToField(AbstractBeanField.java:187)
    ... 7 more
Caused by: java.lang.IllegalArgumentException: Last Salary cannot be less than First Salary.
    at integrationTest.BeanTests.SetterBean.setLastSalary(SetterBean.java:33)
    ... 12 more

希望有帮助.

斯科特·康威(Scott Conway):)

Scott Conway :)

这篇关于解析中的Opencsv自定义逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆