diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java index 13179a3a0b..ab8601b18c 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java @@ -533,7 +533,7 @@ public static class DelimitedBuilder { private FieldSetFactory fieldSetFactory = new DefaultFieldSetFactory(); - private final boolean strict = true; + private boolean strict = true; protected DelimitedBuilder(FlatFileItemReaderBuilder parent) { this.parent = parent; @@ -609,6 +609,20 @@ public FlatFileItemReaderBuilder names(String... names) { return this.parent; } + /** + * If true (the default) then the number of tokens in line must match the number + * of tokens defined (by {@link Range}, columns, etc.) in {@link LineTokenizer}. + * If false then lines with less tokens will be tolerated and padded with empty + * columns, and lines with more tokens will simply be truncated. + * + * @since 5.1 + * @param strict the strict flag to set + */ + public DelimitedBuilder strict(boolean strict) { + this.strict = strict; + return this; + } + /** * Returns a {@link DelimitedLineTokenizer} * @return {@link DelimitedLineTokenizer} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilderTests.java index 90b11ef4cd..e6c6f6c2de 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilderTests.java @@ -54,6 +54,7 @@ * @author Michael Minella * @author Mahmoud Ben Hassine * @author Drummond Dawson + * @author Glenn Renfro */ class FlatFileItemReaderBuilderTests { @@ -215,6 +216,43 @@ void testStrict() throws Exception { assertNull(reader.read()); } + @Test + public void testDelimitedRelaxed() throws Exception { + FlatFileItemReader reader = new FlatFileItemReaderBuilder().name("fooReader") + .resource(getResource("1 2 3")) + .delimited() + .delimiter(" ") + .strict(false) + .names("first", "second") + .targetType(Foo.class) + .build(); + + reader.open(new ExecutionContext()); + Foo item = reader.read(); + assertEquals(1, item.getFirst()); + assertEquals(2, item.getSecond()); + assertNull(item.getThird()); + } + + @Test + public void testDelimitedStrict() { + FlatFileItemReader reader = new FlatFileItemReaderBuilder().name("fooReader") + .resource(getResource("1 2 3")) + .delimited() + .delimiter(" ") + .strict(true) + .names("first", "second") + .targetType(Foo.class) + .build(); + + reader.open(new ExecutionContext()); + + Exception exception = assertThrows(RuntimeException.class, reader::read); + String expectedMessage = "Parsing error at line: 1 in resource=[Byte array resource [resource loaded from byte array]], input=[1 2 3]"; + String actualMessage = exception.getMessage(); + assertTrue(actualMessage.contains(expectedMessage)); + } + @Test void testCustomLineTokenizerFieldSetMapper() throws Exception { FlatFileItemReader reader = new FlatFileItemReaderBuilder().name("fooReader")