diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java index 48787430f1..c1b49fb4bd 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ * * @param type of the target object * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public class GsonJsonObjectReader implements JsonObjectReader { @@ -102,4 +103,11 @@ public void close() throws Exception { this.jsonReader.close(); } + @Override + public void jumpToItem(int itemIndex) throws Exception { + for (int i = 0; i < itemIndex; i++) { + this.jsonReader.skipValue(); + } + } + } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java index 04d7a7b970..df1879240c 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ * * @param type of the target object * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public class JacksonJsonObjectReader implements JsonObjectReader { @@ -98,4 +99,13 @@ public void close() throws Exception { this.jsonParser.close(); } + @Override + public void jumpToItem(int itemIndex) throws Exception { + for (int i = 0; i < itemIndex; i++) { + if (this.jsonParser.nextToken() == JsonToken.START_OBJECT) { + this.jsonParser.skipChildren(); + } + } + } + } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java index c39f9886ea..a7fdc830f1 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 the original author or authors. + * Copyright 2018-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ * * @param the type of json objects to read * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public class JsonItemReader extends AbstractItemCountingItemStreamItemReader @@ -136,4 +137,9 @@ protected void doClose() throws Exception { this.jsonObjectReader.close(); } + @Override + protected void jumpToItem(int itemIndex) throws Exception { + this.jsonObjectReader.jumpToItem(itemIndex); + } + } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java index 5793d2e092..df67a45a21 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ * * @param type of the target object * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public interface JsonObjectReader { @@ -54,4 +55,18 @@ default void close() throws Exception { } + /** + * Move to the given item index. Subclasses should override this method if there is a + * more efficient way of moving to given index than re-reading the input using + * {@link #read()}. + * @param itemIndex index of item (0 based) to jump to. + * @throws Exception Allows subclasses to throw checked exceptions for interpretation + * by the framework + */ + default void jumpToItem(int itemIndex) throws Exception { + for (int i = 0; i < itemIndex; i++) { + read(); + } + } + } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java index 665356f1c1..9db18f97ee 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 the original author or authors. + * Copyright 2018-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -130,4 +130,25 @@ void testInvalidResourceContent() { assertTrue(getJsonParsingException().isInstance(expectedException.getCause())); } + @Test + void testJumpToItem() throws Exception { + // given + JsonItemReader itemReader = new JsonItemReaderBuilder().jsonObjectReader(getJsonObjectReader()) + .resource(new ClassPathResource("org/springframework/batch/item/json/trades.json")) + .name("tradeJsonItemReader") + .build(); + itemReader.open(new ExecutionContext()); + + // when + itemReader.jumpToItem(3); + + // then + Trade trade = itemReader.read(); + assertNotNull(trade); + assertEquals("100", trade.getIsin()); + assertEquals("barfoo", trade.getCustomer()); + assertEquals(new BigDecimal("1.8"), trade.getPrice()); + assertEquals(4, trade.getQuantity()); + } + }