以新行分隔的JSON,示例:
{"summersolstice":"21st June, 2019", //complex objects, arrays, etc ... }
{"summersolstice":"21st June, 2018", //complex objects, arrays, etc ... }
{"summersolstice":"21st June, 2017", //complex objects, arrays, etc ... }
虽然我了解最好的方法是使用去年夏天(link)发布的崭新的JSON项目阅读器开发人员,但将批处理版本更新为最新版本尚不可行。那是唯一的约束。
到目前为止,我一直遵循this堆栈答案,但是我不认为为T
使用FlatFileItemReader
是最好的策略!
到目前为止,我只是将其与以下代码一起使用:
Map<String, Object>
...然后在ItemProcessor中对其进行简单解析,例如:
public class JsonItemReader extends FlatFileItemReader<Map<String, Object>> {
public JsonItemReader(File file) {
Resource resource = new BzipLazyResource(file); //on the fly unzipping
setResource(resource);
setLineMapper(new JsonLineMapper());
}
public JsonItemReader(String sourceFileName) {
this(new File(sourceFileName));
}
}
答案 0 :(得分:1)
通过扩展FlatFileItemReader
并创建一个额外的项目处理器来将Map<String, Object>
转换为List<Json>
,就不需要这种间接。
这是一个可以与FlatFileItemReader
一起使用的快速行映射器:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.batch.item.file.LineMapper;
public class NDJsonLineMapper<T> implements LineMapper<T> {
private Class<? extends T> targetType;
private ObjectMapper objectMapper = new ObjectMapper(); // TODO could make this configurable
public NDJsonLineMapper(Class<? extends T> targetType) {
this.targetType = targetType;
}
@Override
public T mapLine(String line, int lineNumber) throws Exception {
return objectMapper.readValue(line, targetType);
}
}
及其测试:
import org.junit.Assert;
import org.junit.jupiter.api.Test;
class NDJsonLineMapperTest {
@Test
void testNDJsonMapping() throws Exception {
// given
String jsonLine = "{\"id\":1,\"name\":\"foo\"}";
NDJsonLineMapper<Person> lineMapper = new NDJsonLineMapper<>(Person.class);
// when
Person person = lineMapper.mapLine(jsonLine, 1);
// then
Assert.assertEquals(1, person.getId());
Assert.assertEquals("foo", person.getName());
}
static class Person {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
这是您共享的链接中选项1.2的示例。您可以将其与FlatFileItemReader
一起使用,如下所示:
@Bean
public FlatFileItemReader<Person> itemReader() {
return new FlatFileItemReaderBuilder<Person>()
.name("NDJsonItemReader")
.resource(new FileSystemResource("file.ndjson"))
.lineMapper(new NDJsonLineMapper<>(Person.class))
.build();
}
希望这会有所帮助。