@@ -44,13 +44,13 @@ public class ItemFailureLoggerListener extends ItemListenerSupport {
44
44
logger.error("Encountered error on read", e);
45
45
}
46
46
47
- public void onWriteError(Exception ex, Object item ) {
47
+ public void onWriteError(Exception ex, List<? extends Object> items ) {
48
48
logger.error("Encountered error on write", ex);
49
49
}
50
50
}
51
51
----
52
52
53
- Having implemented this listener it, must be registered with a step, as shown in the
53
+ Having implemented this listener, it must be registered with a step, as shown in the
54
54
following example:
55
55
56
56
.XML Configuration
@@ -78,7 +78,7 @@ public Step simpleStep() {
78
78
}
79
79
----
80
80
81
- Remember that, if your listener does anything in an `onError()` method, it must be inside
81
+ NOTE: if your listener does anything in an `onError()` method, it must be inside
82
82
a transaction that is going to be rolled back. If you need to use a transactional
83
83
resource, such as a database, inside an `onError()` method, consider adding a declarative
84
84
transaction to that method (see Spring Core Reference Guide for details), and giving its
@@ -98,12 +98,14 @@ in the following example:
98
98
99
99
[source, java]
100
100
----
101
- public class PoisonPillItemWriter implements ItemWriter< T> {
101
+ public class PoisonPillItemProcessor<T> implements ItemProcessor<T, T> {
102
102
103
- public void write(T item) throws Exception {
103
+ @Override
104
+ public T process(T item) throws Exception {
104
105
if (isPoisonPill(item)) {
105
106
throw new PoisonPillException("Poison pill detected: " + item);
106
- }
107
+ }
108
+ return item;
107
109
}
108
110
}
109
111
----
@@ -259,7 +261,7 @@ public class TradeItemWriter implements ItemWriter<Trade>,
259
261
260
262
private BigDecimal totalAmount = BigDecimal.ZERO;
261
263
262
- public void write(List<? extends Trade> items) {
264
+ public void write(List<? extends Trade> items) throws Exception {
263
265
BigDecimal chunkTotal = BigDecimal.ZERO;
264
266
for (Trade trade : items) {
265
267
chunkTotal = chunkTotal.add(trade.getAmount());
@@ -282,7 +284,7 @@ public class TradeItemWriter implements ItemWriter<Trade>,
282
284
This `TradeItemWriter` stores a `totalAmount` value that is increased with the `amount`
283
285
from each `Trade` item written. After the last `Trade` is processed, the framework calls
284
286
`writeFooter`, which puts the `totalAmount` into the file. Note that the `write` method
285
- makes use of a temporary variable, `chunkTotalAmount `, that stores the total of the
287
+ makes use of a temporary variable, `chunkTotal `, that stores the total of the
286
288
`Trade` amounts in the chunk. This is done to ensure that, if a skip occurs in the
287
289
`write` method, the `totalAmount` is left unchanged. It is only at the end of the `write`
288
290
method, once we are guaranteed that no exceptions are thrown, that we update the
@@ -384,7 +386,7 @@ into a full 'Foo' object. An existing DAO can be used to query for the full obje
384
386
on the key.
385
387
386
388
[[multiLineRecords]]
387
- ==== Multi-Line Records
389
+ === Multi-Line Records
388
390
389
391
While it is usually the case with flat files that each record is confined to a single
390
392
line, it is common that a file might have records spanning multiple lines with multiple
@@ -419,9 +421,7 @@ do this, a custom `ItemReader` should be implemented as a wrapper for the
419
421
<property name="lineMapper">
420
422
<bean class="org.spr...DefaultLineMapper">
421
423
<property name="lineTokenizer" ref="orderFileTokenizer"/>
422
- <property name="fieldSetMapper">
423
- <bean class="org.spr...PassThroughFieldSetMapper" />
424
- </property>
424
+ <property name="fieldSetMapper" ref="orderFieldSetMapper"/>
425
425
</bean>
426
426
</property>
427
427
</bean>
@@ -445,10 +445,11 @@ public MultiLineTradeItemReader itemReader() {
445
445
public FlatFileItemReader flatFileItemReader() {
446
446
FlatFileItemReader<Trade> reader = new FlatFileItemReaderBuilder<Trade>()
447
447
.name("flatFileItemReader")
448
- .resource(new ClasspathResource ("data/iosample/input/multiLine.txt"))
448
+ .resource(new ClassPathResource ("data/iosample/input/multiLine.txt"))
449
449
.lineTokenizer(orderFileTokenizer())
450
- .fieldSetMapper(new PassThroughFieldSetMapper ())
450
+ .fieldSetMapper(orderFieldSetMapper ())
451
451
.build();
452
+ return reader;
452
453
}
453
454
----
454
455
@@ -490,7 +491,7 @@ public PatternMatchingCompositeLineTokenizer orderFileTokenizer() {
490
491
tokenizers.put("NCU*", customerLineTokenizer());
491
492
tokenizers.put("BAD*", billingAddressLineTokenizer());
492
493
493
- tokenizer.setTokenizers(tokenizers() );
494
+ tokenizer.setTokenizers(tokenizers);
494
495
495
496
return tokenizer;
496
497
}
@@ -578,11 +579,11 @@ exceptional. The `Step` is simply considered to have found no work and completes
578
579
items read. All of the `ItemReader` implementations provided out of the box in Spring
579
580
Batch default to this approach. This can lead to some confusion if nothing is written out
580
581
even when input is present (which usually happens if a file was misnamed or some similar
581
- issue arises) For this reason, the metadata itself should be inspected to determine how
582
+ issue arises). For this reason, the metadata itself should be inspected to determine how
582
583
much work the framework found to be processed. However, what if finding no input is
583
584
considered exceptional? In this case, programmatically checking the metadata for no items
584
585
processed and causing failure is the best solution. Because this is a common use case,
585
- Spring Batch provides a listener is provided with exactly this functionality, as shown in
586
+ Spring Batch provides a listener with exactly this functionality, as shown in
586
587
the class definition for `NoWorkFoundStepExecutionListener`:
587
588
588
589
[source, java]
@@ -644,7 +645,7 @@ To make the data available to future `Steps`, it must be "promoted" to the `Job`
644
645
with the keys related to the data in the `ExecutionContext` that must be promoted. It can
645
646
also, optionally, be configured with a list of exit code patterns for which the promotion
646
647
should occur (`COMPLETED` is the default). As with all listeners, it must be registered
647
- on the`Step` as shown in the following example:
648
+ on the `Step` as shown in the following example:
648
649
649
650
.XML Configuration
650
651
[source, xml, role="xmlContent"]
@@ -665,7 +666,11 @@ on the`Step` as shown in the following example:
665
666
</job>
666
667
667
668
<beans:bean id="promotionListener" class="org.spr....ExecutionContextPromotionListener">
668
- <beans:property name="keys" value="someKey"/>
669
+ <beans:property name="keys">
670
+ <list>
671
+ <value>someKey</value>
672
+ </list>
673
+ </beans:property>
669
674
</beans:bean>
670
675
----
671
676
@@ -677,7 +682,6 @@ public Job job1() {
677
682
return this.jobBuilderFactory.get("job1")
678
683
.start(step1())
679
684
.next(step1())
680
- .end()
681
685
.build();
682
686
}
683
687
@@ -695,7 +699,7 @@ public Step step1() {
695
699
public ExecutionContextPromotionListener promotionListener() {
696
700
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
697
701
698
- listener.setKeys("someKey");
702
+ listener.setKeys(new String[] { "someKey" } );
699
703
700
704
return listener;
701
705
}
0 commit comments