3

My approach so far:

@Bean
FlatFileItemReader<Blub> flatFileItemReader() {
    FlatFileItemReader<Blub> reader = new FlatFileItemReader<>();

    reader.setResource(new FileSystemResource("test.json"));

    JsonLineMapper lineMapper = new JsonLineMapper();

    reader.setLineMapper(lineMapper);

    return reader;
}

The challenge is: reader.setLineMapper() cannot use the JsonLineMapper. How to use the JsonLineMapper properly?

yN.
  • 1,847
  • 5
  • 30
  • 47

3 Answers3

6

create a class BlubJsonLineMapper

public class BlubJsonLineMapper implements LineMapper<Blub> {

    private ObjectMapper mapper = new ObjectMapper();


    /**
     * Interpret the line as a Json object and create a Blub Entity from it.
     * 
     * @see LineMapper#mapLine(String, int)
     */
    @Override
    public Blub mapLine(String line, int lineNumber) throws Exception {
        return mapper.readValue(line, Blub.class);
    }

}

then you can set in the FlatFileItemReader

@Bean
FlatFileItemReader<Blub> flatFileItemReader() {
    FlatFileItemReader<Blub> reader = new FlatFileItemReader<>();

    reader.setResource(new FileSystemResource("test.json"));

    BlubJsonLineMapper lineMapper = new BlubJsonLineMapper();

    reader.setLineMapper(lineMapper);

    return reader;
}
clevertension
  • 6,929
  • 3
  • 28
  • 33
  • Ty for your answer! Is there a way to use the JsonLineMapper and not to implement an own LineMapper? – yN. Aug 20 '18 at 10:58
  • JsonLineMapper is convert the everyline json to *Map*, but your requirement is to convert to **Blub**, you can use a anonymous class that implement the LineMapper in your flatFileItemReader() {....} – clevertension Aug 20 '18 at 11:01
4

How to setup a FlatFileItemReader to read a json file?

It depends on the format of your json file:

1. Each line is a json object (known as NDJson)

For example:

{object1}
{object2}

then you have two options:

  • 1.1 Use the JsonLineMapper which returns a Map<String, Object>. In this case, your reader should also return Map<String, Object> and you can use an item processor to transform items from Map<String, Object> to Blub (BTW, transforming data from one type to another is a typical use case for an item processor)
  • 1.2 Use a custom implementation of LineMapper<Blub> based on Jackson or Gson or any other library (as shown in the answer by @clevertension)

2. Lines are wrapped in a json array

For example:

[
 {object1},
 {object2}
]

then you can use the new JsonItemReader that we introduced in version 4.1.0.M1 (See example in the blog post here: https://spring.io/blog/2018/05/31/spring-batch-4-1-0-m1-released#add-a-new-json-item-reader).

There are similar questions to this one, I'm adding them here for reference:

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50
  • I'm fiddling with format 1. which option would you suggest best? I'm complete newbie to Spring batch and I've been shaving my head over how to do this right. Doesn't seem like there is one complete example on the internet for it save for this and a couple other stack answers. Is every batch coder reading JSON is pro already? :O – Rohan Kumar Jun 22 '19 at 19:39
  • I've so far been able to code this: ```public class DbsnpJsonItemReader extends FlatFileItemReader> { public DbsnpJsonItemReader(File file) { Resource resource = new GzipLazyResource(file); setResource(resource); setLineMapper(new JsonLineMapper()); } ``` – Rohan Kumar Jun 22 '19 at 19:41
2

I have build a small demo for Json. If you need any more than it, let me know I can build another example for you

https://github.com/bigzidane/spring-batch-jsonListItem-reader

Community
  • 1
  • 1
Nghia Do
  • 2,588
  • 2
  • 17
  • 31