2

Java ウィザードの皆さん、こんにちは。

春バッチに入るのにとても苦労しています。とりあえず本題へ。フォルダーからすべてのファイル (xml) を処理する必要があり、少し追加してそれらを書き戻します。問題は、入力ファイル名を保持したいということでした。これに対する私が持っている解決策は、StaxEventItemReader を呼び出してマーシャリングされた xml とファイル名を保持するカスタム項目を返すカスタム Itemreader に委任する MultiResourceItemReader です。

質問: 無限ループで同じファイルだけが読み取られ、別の奇妙なことに、毎回 10 回の再試行があります。解決策の 1 つは、ファイルが一度読み取られた後にリーダーが null を返すことですが、それは、処理されたファイルのリストを保持する必要があることを意味します。
今はそうしようと思いますが、もっとスマートなものが欲しいです。

ジョブ構成:

<batch:job id="job1">
    <batch:step id="step1"  >           
        <batch:tasklet transaction-manager="transactionManager" start-limit="100" >
            <batch:chunk reader="reader" writer="writer" commit-interval="10" />
        </batch:tasklet>
     </batch:step>
</batch:job> 

<bean id="reader" class="org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources" value="files/*.xml" />
<property name="delegate" ref="myItemReader" />
</bean>

私のアイテムの読み取り方法、基本的に:

public class MyItemReader implements ResourceAwareItemReaderItemStream<MyItem>, ApplicationContextAware {


public MyItem read() throws Exception, UnexpectedInputException,
        ParseException, NonTransientResourceException {

    StaxEventItemReader<JAXBElement<RootObject>> reader = new StaxEventItemReader<JAXBElement<RootObject>>();
    reader.setResource(currentResource);
    reader.setFragmentRootElementName("RootObject");

    // ... create jaxb unmarshaller

    reader.setUnmarshaller(unmarshaller);

    reader.setSaveState(true);
    reader.afterPropertiesSet();        

    reader.open(executionContext);

    JAXBElement<RootObject> jaxbElem = reader.read();

    MyItem item = new MyItem();

    item.setFilename(currentResource.getFile().getName());
    item.setJaxbElement(jaxbElem);

    return item;
}
}

誰かがここで私をまっすぐにすることができますか?

解決策 したがって、最終的には、読み取ったファイルのリストを保持し、既に読み取られている場合は null を返します。一度に 10 回の読み取りに関しては、まあ、それはチャンクのサイズなので、理にかなっています。

4

2 に答える 2

0

カスタムリーダー内に新しいリーダーを作成したくないと思います。それがあなたの問題を引き起こしているかどうかはわかりませんが、それは正しくないようです (そして、読んだ後に閉じていません)。

Spring を使用して JAXB コンテキストを初期化し、それをカスタム リーダーに挿入するだけです。

http://static.springsource.org/spring-ws/site/reference/html/oxm.html

例:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:oxm="http://www.springframework.org/schema/oxm"
    xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myItemReader" class="com.example.MyItemReader">
        <property name="unmarshaller" ref="jaxbMarshaller"/>
    </bean>

    <oxm:jaxb2-marshaller id="jaxbMarshaller">
        <oxm:class-to-be-bound
            name="com.example.RootObject" />
    </oxm:jaxb2-marshaller>
</beans>

次に、読者のread()方法で、アンマーシャラーを使用するだけです...

public MyItem read() throws Exception, UnexpectedInputException,
        ParseException, NonTransientResourceException {

    Source source = new StreamSource(resource);
    JAXBElement<RootObject> jaxbElem = unmarshaller.unmarshal(source);

    MyItem item = new MyItem();

    item.setFilename(resource.getFile().getName());
    item.setJaxbElement(jaxbElem);

    return item;
}

編集

OK、問題はその方法にあると思いますread()ItemReaderの Javadoc によると、リーダー内のすべての項目が使い果たされると、read()メソッドは null を返す必要があります...そうしているとは思わないので、無期限に読み取ります。

FlatFileItemReader拡張する方法を見つけるか、より良い方法だと思いますStaxEventItemReader...このようなものは機能しませんか?

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:oxm="http://www.springframework.org/schema/oxm"
    xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd
        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <batch:job id="job1">
        <batch:step id="step1"  >           
            <batch:tasklet transaction-manager="transactionManager" start-limit="100" >
                <batch:chunk reader="reader" writer="writer" commit-interval="10" />
            </batch:tasklet>
         </batch:step>
    </batch:job> 

    <bean id="reader" class="org.springframework.batch.item.file.MultiResourceItemReader">
        <property name="resources" value="files/*.xml" />
        <property name="delegate" ref="myItemReader" />
    </bean>

    <bean id="myItemReader" class="com.example.MyItemReader">
        <property name="unmarshaller" ref="jaxbMarshaller"/>
        <property name="fragmentRootElementName" ref="RootObject"/>
    </bean>

    <oxm:jaxb2-marshaller id="jaxbMarshaller">
        <oxm:class-to-be-bound
            name="com.example.RootObject" />
    </oxm:jaxb2-marshaller>
</beans>

読者:

public class MyItemReader<T> extends StaxEventItemReader<T>{

    private Resource resource;

    @Override
    public void setResource(Resource resource) {
        this.resource = resource;
    }

    @Override
    protected T doRead() throws Exception {
        T jaxbElem = (T) super.doRead();

        MyItem item = new MyItem();

        item.setFilename(resource.getFile().getName());
        item.setJaxbElement(jaxbElem);

        return (T) item;
    }

}
于 2013-07-03T13:21:59.537 に答える