使用 spring 批次读取复杂的 json 文件
read complex json file with spring batch
我有一个复杂的 json 文件(带有嵌套的 json 数组)结构如下:
{"persons":[
{"id":"1", "firstName": "X", "lastName": "X", "infos": [{"address":[{"city": "X", "country": "X"}]}]},
{"id":"2", "firstName": "Y", "lastName": "Y", "infos": [{"address":[{"city": "Y", "country": "Y"}]}]}
]}
我想分开看每一行(一个人)
所以我的spring批量配置是这样的
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
<property name="resource" value="#{jobParameters[file]}" />
<property name="recordSeparatorPolicy" ref="recordPolicy" />
<property name="lineMapper" ref="lineMapper" />
</bean>
<bean id="lineMapper"
class="com.batchs.personJob.PersonLineMapper">
<property name="delegate" ref="lineMapperType" />
</bean>
<bean id="lineMapperType"
class="org.springframework.batch.item.file.mapping.JsonLineMapper" />
<bean id="recordPolicy"
class="org.springframework.batch.item.file.separator.JsonRecordSeparatorPolicy" />
映射器class看起来像
public class PersonLineMapper implements LineMapper<Person> {
private JsonLineMapper delegate;
public mapLine(String line, int lineNumber) throws Exception {
Map<String, Object> personAsMap = delegate.mapLine(line, lineNumber);
Person person = new Person();
// map fields
return person ;
}
public void setDelegate(JsonLineMapper delegate) {
this.delegate = delegate;
}
}
问题是 reader 只读取一行(所以一次提交),因为他像读取整行一样读取我的 json 文件中的人员数组,但我想改为每行读取一行(一次一个人)
如何做到这一点?
我试过像这样的简单 json 文件:
{ "id": "1",
"firstName": "X",
"lastName": "X"}
{ "id": "2",
"firstName": "Y",
"lastName": "Y"}
而且效果很好...我一个一个地读了每个人
非常感谢
很遗憾,您有两个选择:
- 编写您自己的忽略包装人员的记录分隔符 element/line。
- 在读取文件之前的一个步骤中编辑该文件,以使用类似 sed 命令的方式删除该包装行。
如果您选择选项2,您可以通过SystemCommandTasklet
在您实际处理的步骤之前的步骤中执行它。
另一种方法是 运行 通过转换步骤来扁平化对象结构的文件,因此您只需处理一组人员。这应该没问题,除非你正在处理大文件。
我有一个复杂的 json 文件(带有嵌套的 json 数组)结构如下:
{"persons":[
{"id":"1", "firstName": "X", "lastName": "X", "infos": [{"address":[{"city": "X", "country": "X"}]}]},
{"id":"2", "firstName": "Y", "lastName": "Y", "infos": [{"address":[{"city": "Y", "country": "Y"}]}]}
]}
我想分开看每一行(一个人)
所以我的spring批量配置是这样的
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
<property name="resource" value="#{jobParameters[file]}" />
<property name="recordSeparatorPolicy" ref="recordPolicy" />
<property name="lineMapper" ref="lineMapper" />
</bean>
<bean id="lineMapper"
class="com.batchs.personJob.PersonLineMapper">
<property name="delegate" ref="lineMapperType" />
</bean>
<bean id="lineMapperType"
class="org.springframework.batch.item.file.mapping.JsonLineMapper" />
<bean id="recordPolicy"
class="org.springframework.batch.item.file.separator.JsonRecordSeparatorPolicy" />
映射器class看起来像
public class PersonLineMapper implements LineMapper<Person> {
private JsonLineMapper delegate;
public mapLine(String line, int lineNumber) throws Exception {
Map<String, Object> personAsMap = delegate.mapLine(line, lineNumber);
Person person = new Person();
// map fields
return person ;
}
public void setDelegate(JsonLineMapper delegate) {
this.delegate = delegate;
}
}
问题是 reader 只读取一行(所以一次提交),因为他像读取整行一样读取我的 json 文件中的人员数组,但我想改为每行读取一行(一次一个人)
如何做到这一点?
我试过像这样的简单 json 文件:
{ "id": "1",
"firstName": "X",
"lastName": "X"}
{ "id": "2",
"firstName": "Y",
"lastName": "Y"}
而且效果很好...我一个一个地读了每个人
非常感谢
很遗憾,您有两个选择:
- 编写您自己的忽略包装人员的记录分隔符 element/line。
- 在读取文件之前的一个步骤中编辑该文件,以使用类似 sed 命令的方式删除该包装行。
如果您选择选项2,您可以通过SystemCommandTasklet
在您实际处理的步骤之前的步骤中执行它。
另一种方法是 运行 通过转换步骤来扁平化对象结构的文件,因此您只需处理一组人员。这应该没问题,除非你正在处理大文件。