当前位置: 首页 > 知识库问答 >
问题:

Spring批处理:如何配置FlatItemFileReader来读取压缩的ND-JSON文件?

严瀚昂
2023-03-14
{"summersolstice":"21st June, 2019", //complex objects, arrays, etc ... }
{"summersolstice":"21st June, 2018", //complex objects, arrays, etc ... }
{"summersolstice":"21st June, 2017", //complex objects, arrays, etc ... }

虽然我知道最好的方法是使用去年夏天发布的闪亮的JSON item reader devs(link),但要将批处理版本更新到最新版本还不可行。这是唯一的限制。

到目前为止,我遵循了这个堆栈答案,但我不认为将FlatFileItemReader作为Map 使用T是最佳策略!到目前为止,我只是用下面的代码来理解它:

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

...然后在项目处理器中简单地解析它,比如:

public class JsonItemProcessor implements ItemProcessor<Map<String, Object>, List<Json>> {

    private ObjectMapper mapper = new ObjectMapper();
    private static final Logger logger = LoggerFactory.getLogger(JsonItemProcessor.class);

    public List<Json> process(Map<String, Object> jsonItem) throws Exception {
        JsonNode jsonNode = mapper.valueToTree(jsonItem);
        return parseJsonItems(jsonNode);
    }

  • Spring Batch:如何设置FlatItemFileReader以读取JSON文件?
  • 如何使用Jackson将HashMap转换为JsonNode
  • 新行分隔JSON
  • 如何实时读取压缩文件
  • 批处理4.1.x JsonItemReader

共有1个答案

金子平
2023-03-14

通过扩展FlatFileItemReader并创建一个附加的项处理器来将映射 转换为列表 ,就不需要这种间接性了。

下面是一个可以与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;
        }
    }

}
@Bean
public FlatFileItemReader<Person> itemReader() {
    return new FlatFileItemReaderBuilder<Person>()
            .name("NDJsonItemReader")
            .resource(new FileSystemResource("file.ndjson"))
            .lineMapper(new NDJsonLineMapper<>(Person.class))
            .build();
}
 类似资料:
  • 我正在尝试创建一个应用程序,该应用程序使用spring-batch-excel扩展名来读取用户通过web界面上传的Excel文件,以便解析Excel文件中的地址。 当代码运行时,没有错误,但我得到的只是我日志中的以下内容。即使我的处理器和Writer中都有log/syso(它们从未被调用过,我所能想象的是它没有正确读取文件,也没有返回要处理/写入的数据)。是的,这个文件有数据,实际上有几千条记录。

  • 到目前为止,我的方法是: 挑战是:不能使用。如何正确使用?

  • 我正在使用Spring批处理设置一个作业服务器。我的JdbcCursorItemReader需要配置sql,该sql在每个作业运行的基础上进行更改。因为sql发生了变化,所以我希望阅读器具有@stepscope,这样我就不需要担心sql的状态性了。 所以我设置了这样一个类: 我在整个服务器上使用基于Java的配置。ItemReader的一个实例的bean如下所示: 启动服务器并运行Spring批处

  • 那么,我该如何应用一个方法将字符串值转换为long呢?

  • 我知道匹配模式解析器,这是Spring批处理提供的。我需要关于如何构造批处理作业的帮助,以便它可以读取循环中的记录类型5和记录类型6。

  • 我有一个包含多个json文件的zip文件。我已解压缩它们,然后使用以下代码从json获取POJO对象: 但我需要使用spring批处理逐个处理这些json文件。有人能帮助我如何在spring批处理中实现这一点吗?我想使用1000块来读取json文件。我的json对象非常复杂。例子: