gpt4 book ai didi

java - 具有自定义委托(delegate)的 MultiResourceItemReader 不断读取同一个文件

转载 作者:行者123 更新时间:2023-11-29 09:01:00 27 4
gpt4 key购买 nike

你好,Java 向导,

我在进入 Spring 批处理时遇到了很多麻烦。现在开门见山。我需要处理一个文件夹中的所有文件(xmls),然后它们将它们写回,并添加少量内容。问题是我想保留输入文件名。我对此的解决方案是一个 MultiResourceItemReader,它委托(delegate)给自定义 Itemreader,后者又调用 StaxEventItemReader 并返回一个包含编码 xml 和文件名的自定义项。

问题:无限循环只读取同一个文件,还有一个奇怪的事情,每次重试10次。我知道一种解决方案是读取器在读取文件后返回 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 次,嗯,这是 block 的大小,所以这是有道理的。

最佳答案

我认为您不想在自定义阅读器中创建新阅读器。我不知道它是否会导致您的问题,但这似乎不对(并且您在阅读后没有关闭它)。

您可以使用 Spring 来初始化您的 JAXB 上下文,然后将它注入(inject)您的自定义阅读器:

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() 方法中,只需使用unmarshaller...

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

编辑

好的,我认为问题出在 read() 方法上。根据 ItemReader 的 Javadoc ,当阅读器中的所有项目都用完时,read() 方法应该返回 null...我不认为你正在这样做,所以它会无限期地阅读。

我认为找到一种方法来扩展 FlatFileItemReaderStaxEventItemReader 是更好的方法...这样的方法行不通吗?

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

}

关于java - 具有自定义委托(delegate)的 MultiResourceItemReader 不断读取同一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17448541/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com