I am creating a Spring Batch job with folowing xml:
<batch:job id="simulatorJob" restartable="false">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="stockListner" writer="customWriter"
commit-interval="5">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="stockListner" class="com.XXX.stock.java.StockReader" scope="step">
<property name="URL" value="NTPC,TCS" />
<!-- <property name="URL" value="NTPC" /> -->
<!-- <property name="URL" value="TCS" /> -->
</bean>
<bean id="customWriter" class="com.XXX.stock.java.FlatFileWriter" />
This is my reader class:
private String URL;
public String getURL() {
return URL;
}
public void setURL(String uRL) {
URL = uRL;
}
public ArrayList<StockData> read() throws Exception, UnexpectedInputException,ParseException, NonTransientResourceException {
ArrayList<StockData> list = new ArrayList<StockData>();
String[] splitStocks = URL.split(",");
for(int i=0; i < splitStocks.length;i++){
list.add(stockReader.getStockData(splitStocks[i]));
}
return list;
}
But the reader class keeps on running. How do I stop at first run?
I tried this aswell:
public StockData read() throws Exception, UnexpectedInputException,ParseException, NonTransientResourceException {
ArrayList<StockData> list = new ArrayList<StockData>();
String[] splitStocks = URL.split(",");
for(int i=0; i < splitStocks.length;i++)
{
return stockReader.getStockData(splitStocks[i]);
}
return null;
}
The read() function goes into loop..
To terminate a step you have to return null from ItemReader. read() so when you process an old object you can set a flag into step-execution context and use it to: prevent other items of current chunk to be processed. prevent chunk processed item writing.
Skipping ItemsDefine a skip-limit on your chunk element to tell Spring how many items can be skipped before the job fails (you might handle a few invalid records, but if you have too many then the input data might be invalid).
Reading flat files in the Spring Batch framework is facilitated by the class called FlatFileItemReader , which provides basic functionality for reading and parsing flat files. The two most important required dependencies of FlatFileItemReader are Resource and LineMapper .
public class StepExecution extends Entity. Batch domain object representation the execution of a step. Unlike JobExecution , there are additional properties related the processing of items such as commit count, etc.
This simple delegate encapsulate one-time reading.
class OneItemReader<T> implements ItemReader<T> {
boolean read = false;
ItemReader<T> delegate;
@Override
public T read() {
if(read) {
return null;
}
T item = delegate.read();
read = true;
return item;
}
}
You can create you own reader without think about one-time reading and wrap it using this small delegate.
Your StockURLReader may be defined as
class StockURLReader implements ItemReader<StockReader> {
String[] tokens = new String[0];
int index = 0;
StockDAO stockReader;
void setURL(String URL) {
this.tokens = URL.split(",");
index = 0;
}
StockData read() {
if(index < tokens.length) {
return stockReader.getStockData(tokens[index++]);
}
return null;
}
}
Create OneTimeReader
and set StockURLReader
as delegate and you have separate StockData reading from one-time reading logic.
If you want to read a group of StockData
the best solution is to create a StockDataListBean
where you store all StockData
read from a splitted URL.
class StockDataListBean {
List<StockData> data = new LinkedList<StockData>();
}
and modify StockURLReader
as:
class StockURLReader implements ItemReader<StockDataListBean> {
String[] URLs = new String[0];
int index;
StockDAO stockReader;
void setURLs(String[] URL) {
this.URLs = URL;
index = 0;
}
StockDataListBean read() {
StockDataListBean item = null;
if(index < URLs.length)
{
item = new StockDataListBean();
for(String token : URLs[index].split(",").length)
{
item.data.add(stockReader.getStockData(token));
}
}
return item;
}
}
Quoting ItemReader.read()
Javadoc:
Reads a piece of input data and advance to the next one. Implementations must return
null
at the end of the input data set.
As such, you need to return null
after the first read to indicate to Spring Batch that there is nothing more to read.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With