How do I use BeanIO minLength record level

170 Views Asked by At

I have beanio mappings file for delimeted file and required check is working but minLength is not working. Could you help with this? Geroge person record line is not showing minLength error for salary empty.

  <record name="detail" minOccurs="0" maxOccurs="unbounded"
   class="com.test.Person">
   <field name="firstName"/>
   <field name="surname"/>
   <field name="salary" minLength="1"/>
   <field name="age" required="true"/>
  </record>

Input:

John|Smith|300000.00|34
Peter|William|800000.00|
Gregory|Rocky||30

Output:

[Person [firstName=John, surname=Smith, salary=300000.0, aget=34], Person [firstName=Gregory, surname=Rocky, salary=0.0, aget=30]]
Errors:
3 : age : [Required field not set]

Java Code: Update

public void readCSVFileUsingBeanIo() throws FileNotFoundException {
        StreamFactory factory = StreamFactory.newInstance();
        factory.loadResource("person.xml");
        StringBuilder rejects = new StringBuilder();

        // read it from the classpath : src/main/resources
        InputStream in = new FileInputStream(new File(
                "person.csv"));
        BeanReader reader = factory.createReader("persons", new InputStreamReader(in));
        reader.setErrorHandler(new BeanReaderErrorHandlerSupport() {
            public void invalidRecord(InvalidRecordException ex) throws Exception {
                for (int i = 0, j = ex.getRecordCount(); i < j; i++) {
                    final int ii = i;
                    if (ex.getRecordContext(i).hasErrors()) {

                        ex.getRecordContext(i).getFieldErrors().keySet().stream().forEach(key -> {
                            rejects.append("\n");
                            rejects.append(ex.getRecordContext(ii).getLineNumber() + " : ");
                            rejects.append(ex.getRecordContext(ii).getRecordText() + " Field(" + key + ") : Error "
                                    + ex.getRecordContext(ii).getFieldErrors(key));
                            
                        });
                        rejects.append("\n");
                    }
                }
            }
        });
        Object record = null;
        List<Person> persons = new ArrayList<Person>();

        while ((record = reader.read()) != null) {
            if ("header".equals(reader.getRecordName())) {

                @SuppressWarnings("unchecked")
                Map<String, Object> header = (Map<String, Object>) record;
                System.out.println(header.get("fileDate"));
            } else if ("detail".equals(reader.getRecordName())) {
                Person person = (Person) record;
                persons.add(person);
            }
        }

        System.out.println(persons);
        System.out.println("Errors:");
        System.out.println(rejects);
    }
2

There are 2 best solutions below

1
Vinicius Duarte On

Change age attribute to required="false" or remove it.

<record name="detail" minOccurs="0" maxOccurs="unbounded" class="com.test.Person">
    <field name="firstName"/>
    <field name="surname"/>
    <field name="salary" minLength="1"/>        
    <field name="age"/>
</record>
0
nicoschl On

You need to include the required="true" attribute on the salary field.

<field name="salary" minLength="1" required="true" />

This then defines the field as required and having a minimum length of 1. This will give you the required behaviour.

The field is treated as optional if you don't set required to true. Even though a field may be optional, it may still have a minimum length requirement, when the field is present.

Play around with the different combinations of required and minLength and you will understand how BeanIO treat these values, for example try

<field name="salary" minLength="1"/>
<field name="salary" minLength="1" required="true" />
<field name="salary" minLength="5"/>
<field name="salary" minLength="5" required="true" />

and this input:

John|Smith|300000.00|34
Peter|William|800000.00|
Gregory|Rocky||30
John|Doe|1|30
Jane|Doe|100.00|30

The reference guide has the following to say about the required attribute on a field:

Set to true if this field is required. If a field is required and its field text is empty, a BeanReader will throw an InvalidRecordException when reading the record. Defaults to false.