diff --git a/json-path/src/main/java/com/jayway/jsonpath/ParseContext.java b/json-path/src/main/java/com/jayway/jsonpath/ParseContext.java index 7aad7292..eb90a057 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/ParseContext.java +++ b/json-path/src/main/java/com/jayway/jsonpath/ParseContext.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; + /** * Parses JSON as specified by the used {@link com.jayway.jsonpath.spi.json.JsonProvider}. */ @@ -34,6 +35,8 @@ public interface ParseContext { DocumentContext parse(File json) throws IOException; + DocumentContext parseUtf8(byte[] json); + @Deprecated DocumentContext parse(URL json) throws IOException; } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/ParseContextImpl.java b/json-path/src/main/java/com/jayway/jsonpath/internal/ParseContextImpl.java index af330977..fcfa1c68 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/ParseContextImpl.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/ParseContextImpl.java @@ -38,6 +38,13 @@ public class ParseContextImpl implements ParseContext { return new JsonContext(obj, configuration); } + @Override + public DocumentContext parseUtf8(byte[] json) { + notEmpty(json, "json bytes can not be null or empty"); + Object obj = configuration.jsonProvider().parse(json); + return new JsonContext(obj, configuration); + } + @Override public DocumentContext parse(InputStream json) { return parse(json, "UTF-8"); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/Utils.java b/json-path/src/main/java/com/jayway/jsonpath/internal/Utils.java index 3e54c49f..e51c874f 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/Utils.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/Utils.java @@ -403,6 +403,26 @@ public final class Utils { return chars; } + /** + *
Validate that the specified argument character sequence is + * neither {@code null} nor a length of zero (no characters); + * otherwise throwing an exception with the specified message. + *
+ *Validate.notEmpty(myString, "The string must not be empty");+ * + * @param bytes the bytes to check, validated not null by this method + * @param message the {@link String#format(String, Object...)} exception message if invalid, not null + * @return the validated character sequence (never {@code null} method for chaining) + * @throws NullPointerException if the character sequence is {@code null} + * @throws IllegalArgumentException if the character sequence is empty + */ + public static byte[] notEmpty(byte[] bytes, String message) { + if (bytes == null || bytes.length == 0) { + throw new IllegalArgumentException(message); + } + return bytes; + } + /** *
Validate that the specified argument character sequence is
* neither {@code null} nor a length of zero (no characters);
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java
index 2b8f6e21..e34277f9 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java
@@ -8,17 +8,18 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.jayway.jsonpath.InvalidJsonException;
import com.jayway.jsonpath.JsonPathException;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+
public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider {
private static final ObjectMapper defaultObjectMapper = new ObjectMapper();
@@ -54,6 +55,16 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider {
}
}
+ @Override
+ public Object parse(byte[] json)
+ throws InvalidJsonException {
+ try {
+ return objectMapper.readTree(json);
+ } catch (IOException e) {
+ throw new InvalidJsonException(e, new String(json, StandardCharsets.UTF_8));
+ }
+ }
+
@Override
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException {
try {
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonProvider.java
index f23fe1a1..32522f55 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonProvider.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonProvider.java
@@ -18,15 +18,16 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.jayway.jsonpath.InvalidJsonException;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
+
public class JacksonJsonProvider extends AbstractJsonProvider {
private static final ObjectMapper defaultObjectMapper = new ObjectMapper();
@@ -73,6 +74,16 @@ public class JacksonJsonProvider extends AbstractJsonProvider {
}
}
+ @Override
+ public Object parse(byte[] json)
+ throws InvalidJsonException {
+ try {
+ return objectReader.readValue(json);
+ } catch (IOException e) {
+ throw new InvalidJsonException(e, new String(json, StandardCharsets.UTF_8));
+ }
+ }
+
@Override
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException {
try {
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JakartaJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JakartaJsonProvider.java
index 2f11ce0b..366de223 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JakartaJsonProvider.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JakartaJsonProvider.java
@@ -1,5 +1,20 @@
package com.jayway.jsonpath.spi.json;
+import com.jayway.jsonpath.InvalidJsonException;
+import com.jayway.jsonpath.JsonPathException;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonString;
+import jakarta.json.JsonStructure;
+import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
+import jakarta.json.stream.JsonParsingException;
+import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
@@ -7,6 +22,7 @@ import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
@@ -19,22 +35,6 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
-import com.jayway.jsonpath.InvalidJsonException;
-import com.jayway.jsonpath.JsonPathException;
-
-import jakarta.json.JsonArray;
-import jakarta.json.JsonArrayBuilder;
-import jakarta.json.JsonBuilderFactory;
-import jakarta.json.JsonException;
-import jakarta.json.JsonNumber;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonObjectBuilder;
-import jakarta.json.JsonReader;
-import jakarta.json.JsonString;
-import jakarta.json.JsonStructure;
-import jakarta.json.JsonValue;
-import jakarta.json.spi.JsonProvider;
-import jakarta.json.stream.JsonParsingException;
public class JakartaJsonProvider extends AbstractJsonProvider {
@@ -69,34 +69,34 @@ public class JakartaJsonProvider extends AbstractJsonProvider {
@Override
public Object parse(String json) throws InvalidJsonException {
- Reader jsonInput = new StringReader(json);
- try (JsonReader jsonReader = defaultJsonProvider.createReader(jsonInput)) {
- JsonStructure jsonStruct = jsonReader.read();
- return mutableJson ? proxyAll(jsonStruct) : jsonStruct;
- } catch (JsonParsingException e) {
- throw new InvalidJsonException(e);
- }
- // not catching a JsonException as it never happens here
+ return parse(new StringReader(json));
+ }
+
+ @Override
+ public Object parse(byte[] json)
+ throws InvalidJsonException {
+ return parse(new InputStreamReader(new ByteArrayInputStream(json), StandardCharsets.UTF_8));
}
@Override
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException {
- Reader jsonInput;
try {
- jsonInput = new InputStreamReader(jsonStream, charset);
+ return parse(new InputStreamReader(jsonStream, charset));
} catch (UnsupportedEncodingException e) {
throw new JsonPathException(e);
}
- try (JsonReader jsonReader = defaultJsonProvider.createReader(jsonInput)) {
- JsonStructure jsonStruct = jsonReader.read();
- return mutableJson ? proxyAll(jsonStruct) : jsonStruct;
- } catch (JsonParsingException e) {
- throw new InvalidJsonException(e);
- } catch (JsonException e) {
- throw new JsonPathException(e);
- }
}
+ private Object parse(Reader jsonInput) {
+ try (JsonReader jsonReader = defaultJsonProvider.createReader(jsonInput)) {
+ JsonStructure jsonStruct = jsonReader.read();
+ return mutableJson ? proxyAll(jsonStruct) : jsonStruct;
+ } catch (JsonParsingException e) {
+ throw new InvalidJsonException(e);
+ }
+ // not catching a JsonException as it never happens here
+ }
+
@Override
public String toJson(Object obj) {
if (obj instanceof JsonObjectBuilder) {
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
index fa7dda41..a7fcd711 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
@@ -15,10 +15,11 @@
package com.jayway.jsonpath.spi.json;
import com.jayway.jsonpath.InvalidJsonException;
-
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
+
public interface JsonProvider {
static final Object UNDEFINED = new Object();
@@ -31,6 +32,15 @@ public interface JsonProvider {
*/
Object parse(String json) throws InvalidJsonException;
+ /**
+ * Parse the given json bytes in UTF-8 encoding
+ * @param json json bytes to parse
+ * @return Object representation of json
+ * @throws InvalidJsonException
+ */
+ default Object parse(byte[] json) throws InvalidJsonException {
+ return parse(new String(json, StandardCharsets.UTF_8));
+ }
/**
* Parse the given json string
* @param jsonStream input stream to parse
diff --git a/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java
index ec9b1810..4b97be9f 100644
--- a/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java
+++ b/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java
@@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingException;
+import java.nio.charset.StandardCharsets;
import org.junit.Test;
import java.io.IOException;
@@ -53,6 +54,13 @@ public class JacksonJsonNodeJsonProviderTest extends BaseTest {
assertThat(node.get("string-property").asText()).isEqualTo("string-value");
}
+ @Test
+ public void bytes_json_can_be_parsed() {
+ ObjectNode node = using(JACKSON_JSON_NODE_CONFIGURATION).parseUtf8(JSON_DOCUMENT.getBytes(StandardCharsets.UTF_8))
+ .read("$");
+ assertThat(node.get("string-property").asText()).isEqualTo("string-value");
+ }
+
@Test
public void always_return_same_object() { // Test because of Bug #211
DocumentContext context = using(JACKSON_JSON_NODE_CONFIGURATION).parse(JSON_DOCUMENT);
diff --git a/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java b/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java
index ef79e22a..83cfe5b5 100644
--- a/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java
+++ b/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java
@@ -1,12 +1,13 @@
package com.jayway.jsonpath;
-import org.junit.Test;
-
import java.util.Date;
+import org.junit.Test;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
+
public class JacksonTest extends BaseTest {
@Test
@@ -25,6 +26,12 @@ public class JacksonTest extends BaseTest {
assertThat(fooBarBaz.bar).isEqualTo(10L);
assertThat(fooBarBaz.baz).isEqualTo(true);
+ fooBarBaz = JsonPath.using(JACKSON_CONFIGURATION).parseUtf8(json.getBytes(UTF_8))
+ .read("$", FooBarBaz.class);
+
+ assertThat(fooBarBaz.foo).isEqualTo("foo");
+ assertThat(fooBarBaz.bar).isEqualTo(10L);
+ assertThat(fooBarBaz.baz).isEqualTo(true);
}
public static class FooBarBaz {
@@ -52,7 +59,11 @@ public class JacksonTest extends BaseTest {
final Object readFromSingleQuote = JsonPath.using(JACKSON_CONFIGURATION).parse(jsonArray).read("$.[?(@.foo in ['bar'])].foo");
final Object readFromDoubleQuote = JsonPath.using(JACKSON_CONFIGURATION).parse(jsonArray).read("$.[?(@.foo in [\"bar\"])].foo");
assertThat(readFromSingleQuote).isEqualTo(readFromDoubleQuote);
-
+ final Object readFromSingleQuoteBytes = JsonPath.using(JACKSON_CONFIGURATION).parseUtf8(jsonArray.getBytes(UTF_8))
+ .read("$.[?(@.foo in ['bar'])].foo");
+ final Object readFromDoubleQuoteBytes = JsonPath.using(JACKSON_CONFIGURATION).parseUtf8(jsonArray.getBytes(UTF_8))
+ .read("$.[?(@.foo in [\"bar\"])].foo");
+ assertThat(readFromSingleQuoteBytes).isEqualTo(readFromDoubleQuoteBytes);
}
}
diff --git a/json-path/src/test/java/com/jayway/jsonpath/JakartaJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/JakartaJsonProviderTest.java
index c7ecd0d6..967c2957 100644
--- a/json-path/src/test/java/com/jayway/jsonpath/JakartaJsonProviderTest.java
+++ b/json-path/src/test/java/com/jayway/jsonpath/JakartaJsonProviderTest.java
@@ -1,20 +1,20 @@
package com.jayway.jsonpath;
-import org.junit.Test;
-
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
-
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.junit.Test;
import static com.jayway.jsonpath.JsonPath.parse;
import static com.jayway.jsonpath.JsonPath.using;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.emptyMap;
import static org.assertj.core.api.Assertions.assertThat;
+
public class JakartaJsonProviderTest extends BaseTest {
private static final Map