Comments (13)
It doesn't help to tell Jackson not to use DoubleNode
, because that's what JSLT uses internally. I didn't want to use BigDecimal
internally for performance reasons.
But if your consumer uses a JSON parser that can't read 1.8E7
then ... well ... it's a part of JSON, so their JSON parser is broken.
from jslt.
I assume it's the last line here,
output = mapper.writeValueAsString(transformedData);
where the number becomes "1.8E7"
? If so, this is not a JSLT question, since JSLT is returning a JsonNode
with a decimal number in it. The choice to represent it as "1.8E7"
in string form is made by Jackson, not JSLT. I don't think it's possible to modify JSLT (or your JSLT code) to change that.
from jslt.
If its jackson, wouldnt {"amount": 18000000.00000}
also give out the exponential result, but instead it works fine, but not when {"amount": "18000000.00000"}
and we have our Jackson mapper to not use scientific notation
from jslt.
I agree it's strange that Jackson does not appear to be obeying your settings, but to see why I think this has nothing to do with JSLT, try running the code like this:
JsonNode transformedData;
JsonNode inputJson = mapper.readTree("18000000.00000");
output = mapper.writeValueAsString(inputJson);
You should still get "1.8E7"
, even with no JSLT involved at all.
from jslt.
Tried the code, and we are getting expected result
18000000.00000
from jslt.
So it does seem that the number() function is converting it into scientific notation
from jslt.
Nope.
This code:
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.schibsted.spt.data.jslt.Parser;
import com.schibsted.spt.data.jslt.Expression;
import com.schibsted.spt.data.jslt.impl.ExpressionImpl;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonGenerator.Feature;
public class Test {
public static void main(String[] args) throws Exception {
// Create mapper for parsing
ObjectMapper mapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true))
.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
// Enable features to handle long decimal values rather than
// converting them in exponential format
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
mapper.enable(Feature.WRITE_BIGDECIMAL_AS_PLAIN);
// Initialize data and mapping
JsonNode inputJson = mapper.readTree("18000000.00000");
//JsonNode transformedData = template.apply(inputJson);
String output = mapper.writeValueAsString(inputJson);
System.out.println("output: " + output);
}
}
produces:
MacBook-Pro-3:tmp larsga$ java Test
output: 18000000.00000
from jslt.
Hello @larsga, as you have also tried the code, when you do
// Initialize data and mapping
JsonNode inputJson = mapper.readTree("18000000.00000");
//JsonNode transformedData = template.apply(inputJson);
String output = mapper.writeValueAsString(inputJson);
System.out.println("output: " + output);
it outputs 18000000.00000
but initially you mentioned it would return 1.8E7
.
I think there is some confusion. Maybe we can go over the problem statement again.
- While parsing big numbers using jackson and Feature.WRITE_BIGDECIMAL_AS_PLAIN it does not scientific/exponential result, number is in plain text.
- When use JSLT with number() function and parse the big number, returned out put is in scientific/exponential notation. Which we think is unexpected because without JSLT just with jackson it works fine (as tried by both of us), maybe the function is causing some issues?
from jslt.
You're right, of course, I was too quick there. Sorry.
The test above showed that when JSLT is not used, Jackson gives the correct output. Your claim is that putting the string through the number()
function somehow changes that. So let's test that, too.
I get the same result as you: output: 1.8E7
. OK, so something is going on in Jackson.
This code:
// Initialize data and mapping
JsonNode inputJson = mapper.readTree("18000000.00000");
System.out.println("" + inputJson + " " + inputJson.getClass());
inputJson = mapper.readTree("\"18000000.00000\"");
JsonNode transformedData = template.apply(inputJson);
String output = mapper.writeValueAsString(transformedData);
System.out.println("" + transformedData + " " + transformedData.getClass());
produces:
18000000.00000 class com.fasterxml.jackson.databind.node.DecimalNode
1.8E7 class com.fasterxml.jackson.databind.node.DoubleNode
So the problem here is that Jackson is serializing DecimalNode
in a different way from DoubleNode
.
Note that what you are having problems with is the string representation of the number, but JSLT is returning DoubleNode
; that is, a number, not a string. So the problem is still how Jackson converts the number to a string. It's not JSLT that's producing the string, but Jackson.
You've set WRITE_BIGDECIMAL_AS_PLAIN
, but this isn't a BIgDecimal
, but rather a DoubleNode
. If you convert the node to a DecimalNode
the problem goes away. Add this line at the end:
System.out.println("" + DecimalNode.valueOf(transformedData.decimalValue()));
and you get:
18000000.00000 class com.fasterxml.jackson.databind.node.DecimalNode
1.8E7 class com.fasterxml.jackson.databind.node.DoubleNode
1.8E+7
from jslt.
Sorry. Still too quick. I'm in a rush here.
Last line:
System.out.println(mapper.writeValueAsString(DecimalNode.valueOf(transformedData.decimalValue())));
Output:
18000000.00000 class com.fasterxml.jackson.databind.node.DecimalNode
1.8E7 class com.fasterxml.jackson.databind.node.DoubleNode
18000000
from jslt.
Yeah, was able to reproduce the same outcome. Tried out following seting on mapper to not use DoubleNode
ObjectMapper mapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true))
.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true)
.configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true)
.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN, true);
but still it doesnt work. Do you know any solution which can help us to overcome this issue?
from jslt.
I'm afraid I don't know of any way to change Jackson's behaviour here.
But I do have one question for you. Why do you care? It's a perfectly usable serialization of the number.
from jslt.
Yeah, i agree, it shouldnt have mattered so much, but have one cosumer who is not able to convert it back to actual number, will try to convence that this is how it is.
from jslt.
Related Issues (20)
- Precision issue when sum array HOT 7
- generation of JSLT
- Wanted to replace convert the given input to a JSON and get a particular value HOT 2
- I wanted to convert the given input to JSON HOT 13
- equivalent to jolt recursivelySquashNulls HOT 10
- jolt vs jstl
- Capture function only returns one match HOT 7
- is this project still being maintained and developed HOT 3
- no substring function HOT 1
- index-of works on array but not string HOT 3
- string replace should have options for both literal string replacement and regex replacement HOT 10
- builtin function `replace` does not support positional patterns HOT 1
- Potential improvement to the Demo play ground HOT 3
- flatten example does not flatten arrays HOT 1
- max\min against arrays HOT 1
- Some dependencies are old
- Getting most nested info....interesting case
- object matching always has to be the last expression which might affect order HOT 1
- Cant do nested for loop unless used within new array context.
- Demo Playground should support "variables"
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jslt.