2015-10-27 3 views
6

Я создаю Spring Batch работу с folowing XML:Как запустить чтение() функцию только один раз Spring Batch

<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" /> 

Это мой читатель класс:

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;   
} 

Но класс читатель держит при работе. Как я могу остановиться при первом запуске?

Я попробовал этот 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; 
} 

для чтения() функция переходит в петлю ..

ответ

4

Этот простой делегат инкапсулирует чтение одноразовое.

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; 
    } 
} 

Вы можете создать собственный читатель без думать о чтении разового и оберните его с помощью этой небольшой делегат.

Ваш StockURLReader может быть определен как

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; 
    } 
} 

Создать OneTimeReader и установить StockURLReader как делегат и у вас есть отдельный StockData чтения от чтения логики одноразового.
Если вы хотите, чтобы прочитать группу из StockData, лучшим решением является создание StockDataListBean где вы храните все файлы StockData, прочитанные с разделенного URL.

class StockDataListBean { 
    List<StockData> data = new LinkedList<StockData>(); 
} 

и модифицировать StockURLReader как:

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; 
    } 
} 
+0

Как этот код может быть вписан в этот сценарий .. – Aman

+0

Я считаю, что @Aman имеет более одного элемента' StockData' для чтения в отличие от того, что предложила его первая попытка (т. е. объявить 'ArrayList read()'). –

+0

проверить мое редактирование ... –

4

Цитирование ItemReader.read() Javadoc:

считывает часть входных данных и перехода к следующий. Реализации должен вернуть null в конце набора входных данных.

Как таковой, вы должны вернуть null после первого чтения, чтобы указать весенней партии, что читать больше нечего.

+0

Можете ли вы привести пример, как это сделать .. – Aman

+0

Ваш метод 'читать()' должен возвращать только один 'StockData', а не список. Следите за тем, какие части 'splitStocks' вы уже отправили и возвращаете только один' splitStocks [i] 'до тех пор, пока их не будет больше, и верните« null »(или используйте список, как вы начали делать). –

+0

@Gael Если не arraylist, то как я могу отправить несколько значений Aman

1

Вы можете использовать ListIteamReader как это (пример, не тестировался):

public class StockReader extends ListItemReader<StockData> { 

    public StockReader(String URL) { 
     super(createListFromUrl(URL)); 
    } 

    public List<StockData> createListFromUrl(String URL) { 
     // create your ArrayList<StockData> list from URL 
    } 

} 
Смежные вопросы