You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Mikael Andersson Wigander <mi...@pm.me.INVALID> on 2022/04/13 04:35:39 UTC

JSONPath use own ObjectMapper instead of global

Hi

I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.

--------------------------------------------
JacksonMappingProvider.class

public class JacksonMappingProvider implements MappingProvider {

private final ObjectMapper objectMapper;

public JacksonMappingProvider() {
this(new ObjectMapper());
}

public JacksonMappingProvider(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
----------------------------------------------

Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?

I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
The use of Jackson Features are not available.

When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.

My Camel version is 3.14.1

/M

Re: JSONPath use own ObjectMapper instead of global

Posted by Claus Ibsen <cl...@gmail.com>.
On Wed, Apr 13, 2022 at 6:47 AM Mikael Andersson Wigander
<mi...@pm.me.invalid> wrote:
>
> OK, will do that.
>
> However if I use jsonpathWriteAsString then it uses a global Objectmapper but still my problem exists with the numerics, but that is maybe another issue !?
>

I suggest to look at how jackson maps numerics, it ought to have some
features/flags you can configure to control this.
And an unit test is always welcome, and if you have the opportunity
you are welcome to work on a PR.

Its a little bit more difficult for a dataformat as the model is also
represented in camel-core-model / reifier so you need to do code
changes there too.




>
>
>
> /M
>
>
> ------- Original Message -------
> On Wednesday, April 13th, 2022 at 06:44, Claus Ibsen <cl...@gmail.com> wrote:
>
>
> > Hi
> >
> > Ah okay that sounds like a good improvement. You are welcome to create a JIRA.
> >
> > On Wed, Apr 13, 2022 at 6:35 AM Mikael Andersson Wigander
> > mikael.andersson.wigander@pm.me.invalid wrote:
> >
> > > Hi
> > >
> > > I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.
> > >
> > > --------------------------------------------
> > > JacksonMappingProvider.class
> > >
> > > public class JacksonMappingProvider implements MappingProvider {
> > >
> > > private final ObjectMapper objectMapper;
> > >
> > > public JacksonMappingProvider() {
> > > this(new ObjectMapper());
> > > }
> > >
> > > public JacksonMappingProvider(ObjectMapper objectMapper) {
> > > this.objectMapper = objectMapper;
> > > }
> > > ----------------------------------------------
> > >
> > > Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?
> > >
> > > I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
> > > The use of Jackson Features are not available.
> > >
> > > When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.
> > >
> > > My Camel version is 3.14.1
> > >
> > >
> > > /M
> >
> >
> >
> >
> > --
> > Claus Ibsen
> > -----------------
> > http://davsclaus.com @davsclaus
> > Camel in Action 2: https://www.manning.com/ibsen2



-- 
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2

Re: JSONPath use own ObjectMapper instead of global

Posted by Karen Lease <ka...@gmail.com>.
Yes, what you say is true. And this provider is used to parse the input 
json content which produces some kind of Object after evaluating the path.

Maybe I've misunderstood your problem with the numbers. The default 
mapper is parsing them as Doubles.
So if you don't wnat Doubles then I agree that the default ObjectMapper 
is the problem.
But if the issue is the way the Double is written out in log() or some 
other processing later in your route, then the issue is not with the 
default ObjectMapper.

I also added a comment in the JIRA issue to clarify where the 
JacksonJsonAdapter is used.


On 28/04/2022 13:44, Mikael Andersson Wigander wrote:
> Hmm, not sure if this correct…
> 
> When the JsonPathExpression is instantiated an engine is created.
> The engine is built out of JsonPathEngine and it assigns a JsonProvider as a JacksonJsonProvider.
> This provider is defaulting to use its own default ObjectMapper.
> 
> 
> 
> 
> 
> 
> /M
> 
> 
> ------- Original Message -------
> On Wednesday, April 27th, 2022 at 18:27, Karen Lease <ka...@gmail.com> wrote:
> 
> 
>> I had a look at the JIRA issue you created for this.
>> The JacksonMappingProvider is used only to read the Json, not to write it.
>>
>> With jsonpathWriteAsString, you'd need to register an ObjectMapper which
>> customizes the serialization of the double values. By default, Jackson
>> will use the standard Java String representation for a double which uses
>> the scientific notation.
>>
>> When using jsonpath(), the result type in your example is actually a Map
>> where the values are Doubles. log("${body}") doesn't use an ObjectMapper
>> at all; it just converts the keys and values to a String.
>> However you could use a customer processor to format the Doubles as you
>> want. For example:
>> .jsonpath("$").process(new Processor() {
>> public void process(Exchange exchange) {
>> Object body = exchange.getIn().getBody();
>> if (body instanceof Map) {
>> for (Object value : ((Map)body).values()) {
>> if (value instanceof Double) {
>> String d = String.format("%12.2f", value);
>> ...
>> Is that helpful?
>>
>> Karen Lease
>>
>> On 13/04/2022 06:47, Mikael Andersson Wigander wrote:
>>
>>> OK, will do that.
>>>
>>> However if I use jsonpathWriteAsString then it uses a global Objectmapper but still my problem exists with the numerics, but that is maybe another issue !?
>>>
>>>
>>> /M
>>>
>>> ------- Original Message -------
>>> On Wednesday, April 13th, 2022 at 06:44, Claus Ibsen claus.ibsen@gmail.com wrote:
>>>
>>>> Hi
>>>>
>>>> Ah okay that sounds like a good improvement. You are welcome to create a JIRA.
>>>>
>>>> On Wed, Apr 13, 2022 at 6:35 AM Mikael Andersson Wigander
>>>> mikael.andersson.wigander@pm.me.invalid wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.
>>>>>
>>>>> --------------------------------------------
>>>>> JacksonMappingProvider.class
>>>>>
>>>>> public class JacksonMappingProvider implements MappingProvider {
>>>>>
>>>>> private final ObjectMapper objectMapper;
>>>>>
>>>>> public JacksonMappingProvider() {
>>>>> this(new ObjectMapper());
>>>>> }
>>>>>
>>>>> public JacksonMappingProvider(ObjectMapper objectMapper) {
>>>>> this.objectMapper = objectMapper;
>>>>> }
>>>>> ----------------------------------------------
>>>>>
>>>>> Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?
>>>>>
>>>>> I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
>>>>> The use of Jackson Features are not available.
>>>>>
>>>>> When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.
>>>>>
>>>>> My Camel version is 3.14.1
>>>>>
>>>>> /M
>>>>
>>>> --
>>>> Claus Ibsen
>>>> -----------------
>>>> http://davsclaus.com @davsclaus
>>>> Camel in Action 2: https://www.manning.com/ibsen2

Re: JSONPath use own ObjectMapper instead of global

Posted by Mikael Andersson Wigander <mi...@pm.me.INVALID>.
Hmm, not sure if this correct…

When the JsonPathExpression is instantiated an engine is created.
The engine is built out of JsonPathEngine and it assigns a JsonProvider as a JacksonJsonProvider.
This provider is defaulting to use its own default ObjectMapper.






/M


------- Original Message -------
On Wednesday, April 27th, 2022 at 18:27, Karen Lease <ka...@gmail.com> wrote:


> I had a look at the JIRA issue you created for this.
> The JacksonMappingProvider is used only to read the Json, not to write it.
>
> With jsonpathWriteAsString, you'd need to register an ObjectMapper which
> customizes the serialization of the double values. By default, Jackson
> will use the standard Java String representation for a double which uses
> the scientific notation.
>
> When using jsonpath(), the result type in your example is actually a Map
> where the values are Doubles. log("${body}") doesn't use an ObjectMapper
> at all; it just converts the keys and values to a String.
> However you could use a customer processor to format the Doubles as you
> want. For example:
> .jsonpath("$").process(new Processor() {
> public void process(Exchange exchange) {
> Object body = exchange.getIn().getBody();
> if (body instanceof Map) {
> for (Object value : ((Map)body).values()) {
> if (value instanceof Double) {
> String d = String.format("%12.2f", value);
> ...
> Is that helpful?
>
> Karen Lease
>
> On 13/04/2022 06:47, Mikael Andersson Wigander wrote:
>
> > OK, will do that.
> >
> > However if I use jsonpathWriteAsString then it uses a global Objectmapper but still my problem exists with the numerics, but that is maybe another issue !?
> >
> >
> > /M
> >
> > ------- Original Message -------
> > On Wednesday, April 13th, 2022 at 06:44, Claus Ibsen claus.ibsen@gmail.com wrote:
> >
> > > Hi
> > >
> > > Ah okay that sounds like a good improvement. You are welcome to create a JIRA.
> > >
> > > On Wed, Apr 13, 2022 at 6:35 AM Mikael Andersson Wigander
> > > mikael.andersson.wigander@pm.me.invalid wrote:
> > >
> > > > Hi
> > > >
> > > > I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.
> > > >
> > > > --------------------------------------------
> > > > JacksonMappingProvider.class
> > > >
> > > > public class JacksonMappingProvider implements MappingProvider {
> > > >
> > > > private final ObjectMapper objectMapper;
> > > >
> > > > public JacksonMappingProvider() {
> > > > this(new ObjectMapper());
> > > > }
> > > >
> > > > public JacksonMappingProvider(ObjectMapper objectMapper) {
> > > > this.objectMapper = objectMapper;
> > > > }
> > > > ----------------------------------------------
> > > >
> > > > Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?
> > > >
> > > > I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
> > > > The use of Jackson Features are not available.
> > > >
> > > > When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.
> > > >
> > > > My Camel version is 3.14.1
> > > >
> > > > /M
> > >
> > > --
> > > Claus Ibsen
> > > -----------------
> > > http://davsclaus.com @davsclaus
> > > Camel in Action 2: https://www.manning.com/ibsen2

Re: JSONPath use own ObjectMapper instead of global

Posted by Karen Lease <ka...@gmail.com>.
I had a look at the JIRA issue you created for this.
The JacksonMappingProvider is used only to read the Json, not to write it.

With jsonpathWriteAsString, you'd need to register an ObjectMapper which 
customizes the serialization of the double values. By default, Jackson 
will use the standard Java String representation for a double which uses 
the scientific notation.

When using jsonpath(), the result type in your example is actually a Map 
where the values are Doubles. log("${body}") doesn't use an ObjectMapper 
at all; it just converts the keys and values to a String.
However you could use a customer processor to format the Doubles as you 
want. For example:
.jsonpath("$").process(new Processor() {
    public void process(Exchange exchange) {
      Object body = exchange.getIn().getBody();
      if (body instanceof Map) {
        for (Object value : ((Map)body).values()) {
          if (value instanceof Double) {
             String d = String.format("%12.2f", value);
...
Is that helpful?

Karen Lease

On 13/04/2022 06:47, Mikael Andersson Wigander wrote:
> OK, will do that.
> 
> However if I use jsonpathWriteAsString then it uses a global Objectmapper but still my problem exists with the numerics, but that is maybe another issue !?
> 
> 
> 
> 
> /M
> 
> 
> ------- Original Message -------
> On Wednesday, April 13th, 2022 at 06:44, Claus Ibsen <cl...@gmail.com> wrote:
> 
> 
>> Hi
>>
>> Ah okay that sounds like a good improvement. You are welcome to create a JIRA.
>>
>> On Wed, Apr 13, 2022 at 6:35 AM Mikael Andersson Wigander
>> mikael.andersson.wigander@pm.me.invalid wrote:
>>
>>> Hi
>>>
>>> I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.
>>>
>>> --------------------------------------------
>>> JacksonMappingProvider.class
>>>
>>> public class JacksonMappingProvider implements MappingProvider {
>>>
>>> private final ObjectMapper objectMapper;
>>>
>>> public JacksonMappingProvider() {
>>> this(new ObjectMapper());
>>> }
>>>
>>> public JacksonMappingProvider(ObjectMapper objectMapper) {
>>> this.objectMapper = objectMapper;
>>> }
>>> ----------------------------------------------
>>>
>>> Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?
>>>
>>> I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
>>> The use of Jackson Features are not available.
>>>
>>> When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.
>>>
>>> My Camel version is 3.14.1
>>>
>>>
>>> /M
>>
>>
>>
>>
>> --
>> Claus Ibsen
>> -----------------
>> http://davsclaus.com @davsclaus
>> Camel in Action 2: https://www.manning.com/ibsen2

Re: JSONPath use own ObjectMapper instead of global

Posted by Mikael Andersson Wigander <mi...@pm.me.INVALID>.
OK, will do that.

However if I use jsonpathWriteAsString then it uses a global Objectmapper but still my problem exists with the numerics, but that is maybe another issue !?




/M


------- Original Message -------
On Wednesday, April 13th, 2022 at 06:44, Claus Ibsen <cl...@gmail.com> wrote:


> Hi
>
> Ah okay that sounds like a good improvement. You are welcome to create a JIRA.
>
> On Wed, Apr 13, 2022 at 6:35 AM Mikael Andersson Wigander
> mikael.andersson.wigander@pm.me.invalid wrote:
>
> > Hi
> >
> > I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.
> >
> > --------------------------------------------
> > JacksonMappingProvider.class
> >
> > public class JacksonMappingProvider implements MappingProvider {
> >
> > private final ObjectMapper objectMapper;
> >
> > public JacksonMappingProvider() {
> > this(new ObjectMapper());
> > }
> >
> > public JacksonMappingProvider(ObjectMapper objectMapper) {
> > this.objectMapper = objectMapper;
> > }
> > ----------------------------------------------
> >
> > Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?
> >
> > I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
> > The use of Jackson Features are not available.
> >
> > When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.
> >
> > My Camel version is 3.14.1
> >
> >
> > /M
>
>
>
>
> --
> Claus Ibsen
> -----------------
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2

Re: JSONPath use own ObjectMapper instead of global

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Ah okay that sounds like a good improvement. You are welcome to create a JIRA.

On Wed, Apr 13, 2022 at 6:35 AM Mikael Andersson Wigander
<mi...@pm.me.invalid> wrote:
>
> Hi
>
> I have discovered that when using JSONPath in a route, the implementation does not use any ObjectMapper registered, it uses it's own.
>
> --------------------------------------------
> JacksonMappingProvider.class
>
> public class JacksonMappingProvider implements MappingProvider {
>
> private final ObjectMapper objectMapper;
>
> public JacksonMappingProvider() {
> this(new ObjectMapper());
> }
>
> public JacksonMappingProvider(ObjectMapper objectMapper) {
> this.objectMapper = objectMapper;
> }
> ----------------------------------------------
>
> Is this the intended solution or should we make JSONPath use any globally registered mapper as an option?
>
> I have an issue when using JSONPath and my values are numerics and large decimal format like 123.456789. They get parsed as Double and then when representing the json string they are in scientific notation.
> The use of Jackson Features are not available.
>
> When using json as Dataformat we can register a global Objectmapper and use that but when using JSONPath it is not implemented.
>
> My Camel version is 3.14.1
>
> /M



-- 
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2