| ## JSonPath Language |
| |
| *Available as of Camel version 2.13* |
| |
| Camel supports https://code.google.com/p/json-path/[JSonPath] to allow |
| using link:expression.html[Expression] or link:predicate.html[Predicate] |
| on json messages. |
| |
| [source,java] |
| ----------------------------------------------------- |
| from("queue:books.new") |
| .choice() |
| .when().jsonpath("$.store.book[?(@.price < 10)]") |
| .to("jms:queue:book.cheap") |
| .when().jsonpath("$.store.book[?(@.price < 30)]") |
| .to("jms:queue:book.average") |
| .otherwise() |
| .to("jms:queue:book.expensive") |
| ----------------------------------------------------- |
| |
| ### JSonPath Options |
| |
| |
| // language options: START |
| The JSonPath language supports 5 options which are listed below. |
| |
| |
| |
| [width="100%",cols="2,1m,1m,6",options="header"] |
| |======================================================================= |
| | Name | Default | Java Type | Description |
| | resultType | | String | Sets the class name of the result type (type from output) |
| | suppressExceptions | false | Boolean | Whether to suppress exceptions such as PathNotFoundException. |
| | allowSimple | true | Boolean | Whether to allow in inlined simple exceptions in the json path expression |
| | allowEasyPredicate | true | Boolean | Whether to allow using the easy predicate parser to pre-parse predicates. |
| | trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks |
| |======================================================================= |
| // language options: END |
| |
| |
| |
| ### Using XML configuration |
| |
| If you prefer to configure your routes in your link:spring.html[Spring] |
| XML file then you can use link:jsonpath.html[JSonPath] expressions as |
| follows |
| |
| [source,xml] |
| ------------------------------------------------------------------------- |
| <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> |
| <route> |
| <from uri="direct:start"/> |
| <choice> |
| <when> |
| <jsonpath>$.store.book[?(@.price < 10)]</jsonpath> |
| <to uri="mock:cheap"/> |
| </when> |
| <when> |
| <jsonpath>$.store.book[?(@.price < 30)]</jsonpath> |
| <to uri="mock:average"/> |
| </when> |
| <otherwise> |
| <to uri="mock:expensive"/> |
| </otherwise> |
| </choice> |
| </route> |
| </camelContext> |
| ------------------------------------------------------------------------- |
| |
| ### Syntax |
| |
| See the https://code.google.com/p/json-path/[JSonPath] project page for |
| further examples. |
| |
| ### Easy Syntax |
| |
| *Available as of Camel 2.19* |
| |
| When you just want to define a basic predicate using jsonpath syntax it can be a bit hard to remember the syntax. |
| So for example to find out all the cheap books you have to do |
| |
| $.store.book[?(@.price < 20)] |
| |
| However what if you could just write it as |
| |
| store.book.price < 20 |
| |
| And you can omit the path if you just want to look at nodes with a price key |
| |
| price < 20 |
| |
| To support this there is a `EasyPredicateParser` which kicks-in if you have define the predicate |
| using a basic style. That means the predicate must not start with the `$` sign, and only include one operator. |
| |
| The easy syntax is: |
| |
| left OP right |
| |
| You can use Camel simple language in the right operator, eg |
| |
| store.book.price < ${header.limit} |
| |
| |
| |
| |
| ### Supported message body types |
| |
| Camel JSonPath supports message body using the following types: |
| |
| {% raw %} |
| [width="100%",cols="3m,7",options="header"] |
| |======================================================================= |
| | Type | Comment |
| | File | Reading from files |
| | String | Plain strings |
| | Map | Message bodies as `java.util.Map` types |
| | List | Message bodies as `java.util.List` types |
| | POJO | *Optional* If Jackson is on the classpath, then camel-jsonpath |
| is able to use Jackson to read the message body as POJO and convert to `java.util.Map` |
| which is supported by JSonPath. For example you can add `camel-jackson` as dependency to include Jackson. |
| | InputStream | If none of the above types matches, then Camel will attempt to read the message body as an `java.io.InputStream`. |
| |======================================================================= |
| {% endraw %} |
| |
| If a message body is of unsupported type then an exception is thrown by default, however you |
| can configure JSonPath to suppress exceptions (see below) |
| |
| |
| ### Suppress exceptions |
| |
| *Available as of Camel 2.16* |
| |
| By default jsonpath will throw an exception if the json payload does not |
| have a valid path accordingly to the configured jsonpath expression. In |
| some use-cases you may want to ignore this in case the json payload |
| contains optional data. Therefore you can set the option |
| suppressExceptions to true to ignore this as shown: |
| |
| [source,java] |
| --------------------------------------------------- |
| from("direct:start") |
| .choice() |
| // use true to suppress exceptions |
| .when().jsonpath("person.middlename", true) |
| .to("mock:middle") |
| .otherwise() |
| .to("mock:other"); |
| --------------------------------------------------- |
| |
| And in XML DSL: |
| |
| [source,xml] |
| -------------------------------------------------------------------------- |
| <route> |
| <from uri="direct:start"/> |
| <choice> |
| <when> |
| <jsonpath suppressExceptions="true">person.middlename</jsonpath> |
| <to uri="mock:middle"/> |
| </when> |
| <otherwise> |
| <to uri="mock:other"/> |
| </otherwise> |
| </choice> |
| </route> |
| -------------------------------------------------------------------------- |
| |
| |
| |
| This option is also available on the `@JsonPath` annotation. |
| |
| ### Inline Simple exceptions |
| |
| *Available as of Camel 2.18* |
| |
| Its now possible to inlined Simple language expressions in the JSonPath expression using the simple syntax ${xxx}. |
| An example is shown below: |
| |
| [source,java] |
| --------------------------------------------------- |
| from("direct:start") |
| .choice() |
| .when().jsonpath("$.store.book[?(@.price < ${header.cheap})]") |
| .to("mock:cheap") |
| .when().jsonpath("$.store.book[?(@.price < ${header.average})]") |
| .to("mock:average") |
| .otherwise() |
| .to("mock:expensive"); |
| --------------------------------------------------- |
| |
| And in XML DSL: |
| |
| [source,xml] |
| -------------------------------------------------------------------------- |
| <route> |
| <from uri="direct:start"/> |
| <choice> |
| <when> |
| <jsonpath>$.store.book[?(@.price < ${header.cheap})]</jsonpath> |
| <to uri="mock:cheap"/> |
| </when> |
| <when> |
| <jsonpath>$.store.book[?(@.price < ${header.average})]</jsonpath> |
| <to uri="mock:average"/> |
| </when> |
| <otherwise> |
| <to uri="mock:expensive"/> |
| </otherwise> |
| </choice> |
| </route> |
| -------------------------------------------------------------------------- |
| |
| You can turn off support for inlined simple expression by setting the option allowSimple to false as shown: |
| |
| [source,java] |
| --------------------------------------------------- |
| .when().jsonpath("$.store.book[?(@.price < 10)]", false, false) |
| --------------------------------------------------- |
| |
| And in XML DSL: |
| |
| [source,xml] |
| -------------------------------------------------------------------------- |
| <jsonpath allowSimple="false">$.store.book[?(@.price < 10)]</jsonpath> |
| -------------------------------------------------------------------------- |
| |
| |
| ### JSonPath injection |
| |
| You can use link:bean-integration.html[Bean Integration] to invoke a |
| method on a bean and use various languages such as JSonPath to extract a |
| value from the message and bind it to a method parameter. |
| |
| For example |
| |
| [source,java] |
| --------------------------------------------------------------------------------------------------- |
| public class Foo { |
| |
| @Consume(uri = "activemq:queue:books.new") |
| public void doSomething(@JsonPath("$.store.book[*].author") String author, @Body String json) { |
| // process the inbound message here |
| } |
| } |
| --------------------------------------------------------------------------------------------------- |
| |
| ### Encoding Detection |
| |
| *Since Camel version 2.16*, the encoding of the JSON document is |
| detected automatically, if the document is encoded in unicode (UTF-8, |
| UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE ) as specified in RFC-4627. If |
| the encoding is a non-unicode encoding, you can either make sure that |
| you enter the document in String format to the JSONPath component or you |
| can specify the encoding in the header "*CamelJsonPathJsonEncoding*" |
| (JsonpathConstants.HEADER_JSON_ENCODING). |
| |
| ### Dependencies |
| |
| To use JSonPath in your camel routes you need to add the a dependency on |
| *camel-jsonpath* which implements the JSonPath language. |
| |
| If you use maven you could just add the following to your pom.xml, |
| substituting the version number for the latest & greatest release (see |
| link:download.html[the download page for the latest versions]). |
| |
| [source,xml] |
| ----------------------------------------- |
| <dependency> |
| <groupId>org.apache.camel</groupId> |
| <artifactId>camel-jsonpath</artifactId> |
| <version>x.x.x</version> |
| </dependency> |
| ----------------------------------------- |