In spring
batch, if the user wants to decide a Delimiter at run time based on the certain
criteria. Built-in spring batch Tokenizer classes won’t support this feature.
If we use our own customized class instead of using spring provided Tokenizer
class, spring batch throws an error.
Actual Configuration:
<bean
id="defaultTokenizer"
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property
name="delimiter" value="," />
</bean>
<bean
id="fieldSetMapper"
class="com.mapper.CustomDataUploadFieldSetMapper" />
<bean
id="defaultLineMapper"
class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property
name="lineTokenizer"
ref="defaultTokenizer"></property>
<property
name="fieldSetMapper"
ref="fieldSetMapper"></property>
</bean>
<bean
id="customDataItemReader"
class="com.reader.CustomDataLoadReader"
scope="prototype">
<property
name="lineMapper"
ref="defaultLineMapper"></property>
</bean>
|
Here, if
we provide overridden Tokenizer instead of DelimitedLineTokenizer,
spring container will throw an error while server starts up.
We can
overcome this limitation by using anonymous inner bean configuration as
follows.
<bean
id="customDataItemReader"
class="com.reader.customerDataItemReader"
scope="prototype">
<property name="lineMapper">
<bean
class="com.mapper.CustomLineMapper">
<property
name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property
name="delimiter" value="," />
</bean>
</property>
<property
name="fieldSetMapper">
<bean
class="com.mapper.SegmentFieldSetMapper" />
</property>
</bean>
</property>
</bean>
|
Write a CustomLineMapper by extending DefaultLineMapper and
override
mapLine(String
line, int lineNumber) throws Exception method according
to requirements.
Example: Now
we need use pipe(|) symbol as delimiter if existed in the line, else need
to use comma(,) as default delimiter.
public class CustomLineMapper<T> extends DefaultLineMapper<T>
{
private LineTokenizer lineTokenizer;
private FieldSetMapper<CustomerInformationVO>
fieldSetMapper;
public <T> mapLine(String line, int
lineNumber) throws Exception {
try {
setLineTokenizer(new DelimitedLineTokenizer(StringUtils.contains(
line, '|') ? '|' : ','));
return this.fieldSetMapper.mapFieldSet(this.lineTokenizer
.tokenize(line));
} catch (Exception ex) {
throw new FlatFileParseException("Parsing error at line: "
+
lineNumber + ", input=[" + line + "]", ex, line,
lineNumber);
}
}
public LineTokenizer getLineTokenizer() {
return lineTokenizer;
}
public void setLineTokenizer(LineTokenizer lineTokenizer) {
this.lineTokenizer = lineTokenizer;
}
public void afterPropertiesSet() {
Assert.notNull(this.lineTokenizer, "The
LineTokenizer must be set");
Assert.notNull(this.fieldSetMapper, "The
FieldSetMapper must be set");
}
public FieldSetMapper<CustomerInformationVO>
getFieldSetMapper() {
return fieldSetMapper;
}
public void setFieldSetMapper(
FieldSetMapper<CustomerInformationVO>
fieldSetMapper) {
this.fieldSetMapper = fieldSetMapper;
}
}
|
No comments:
Post a Comment