Reputation: 17425
I have a spring batch program where I am writing from database to a fixed format file.
My database table consist of 5 columns. All the columns contain description about some product. The column are of type varchar with each sized 200.
I am reading the descriptions from the columns in to my pojo as 5 String properties viz. desc1, desc2, desc3, desc4, desc5.
My item writer looks like below:
<beans:bean id="DbToFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<beans:property name="resource" value="file:c:\TestData\output.dat" />
<beans:property name="lineAggregator">
<beans:bean class="org.springframework.batch.item.file.transform.FormatterLineAggregator">
<beans:property name="fieldExtractor">
<beans:bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<beans:property name="names" value="desc1, desc2, desc3, desc4, desc5" />
</beans:bean>
</beans:property>
<beans:property name="format" value="%-20s%-30s%-30s%-30s%-30s" />
</beans:bean>
</beans:property>
</beans:bean>
As shown I want desc1 to be in a fixed length field of 20 characters and desc2 through desc4 into fixed length field of 30 characters each into the file.
However, the issue is, I am getting the whole desc string irrespective of the size. That is, if desc1 is 40 characters from database, it is coming as 40 characters in the file as well.
I feel it should only take the first 20 characters and ignore the rest.
What is the issue? Is it a bug or am I doing something wrong ?
Thanks for reading!
Upvotes: 1
Views: 4600
Reputation: 6630
the FormatterLineAggregator uses String.format() under the hood, so you could use the right Formatter syntax(*) to get what you want
two examples to show what you missed in your formatter syntax
wrong:
// formatted to print out 5 characters minimum
String wrong = String.format("%-5s", new Object[]{"1234567890"});
System.out.println(wrong);
// prints: 1234567890
correct:
// formatted to print out 5 characters minimum AND 6 characters maximum
String correct = String.format("%-5.6s", new Object[]{"1234567890"});
System.out.println(correct);
// prints: 123456
(*) this is mentioned in the javadoc of the FormatterLineAggregator too
Upvotes: 3
Reputation: 10649
The simplest solution will be to change your reader, e.g. your can create SQL view over your table or write a custom SQL query like:
select substr(desc1,1,20), substr(desc2,1,20), ... from my_table
Alternatively you can write your own implementation of FieldExtractor
interface that should aggregate BeanWrapperFieldExtractor
. After calling the BeanWrapperFieldExtractor#extract()
it should crop all values by given maximum size.
Upvotes: 1