Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem that JSON deserializes Long into Integer or Double

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly shows you "how to solve the JSON deserialization Long into Integer or Double problem", the content is easy to understand, clear, hope to help you solve the doubt, the following let the editor lead you to study and learn "how to solve the JSON deserialization Long into Integer or Double" this article.

I. background

In your work, you may encounter the problem of JSON serialization of Map, in which the value contains data of type Long, and the problem of reversing the Long Times type conversion exception after deserialization.

This article briefly discusses the problem and gives a solution. if you want to read the suggestions directly, you can go directly to the third part.

2. Research

This article mainly takes three libraries, jackson, gson and fastjson, as examples. The versions are as follows:

Com.fasterxml.jackson.core jackson-core 2.13.0 com.fasterxml.jackson.core jackson-databind 2.13.0 com.alibaba fastjson 1.2.78 Com.google.code.gson gson 2.8.8

Code example

Package json;import com.alibaba.fastjson.JSON;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.ObjectMapper;import com.google.gson.GsonBuilder;import java.util.HashMap;import java.util.Map;public class ObjectDemo {public static void main (String [] args) throws JsonProcessingException {Map dataMap = new HashMap (2); dataMap.put ("aInteger", 1); dataMap.put ("aLong", 2L) String jsonStr = JSON.toJSONString (dataMap); System.out.println (jsonStr); / / fastjson System.out.println ("- fastjson -"); Map fastMap = JSON.parseObject (jsonStr, new com.alibaba.fastjson.TypeReference () {}); printMap (fastMap); System.out.println ("--gson -") Map gsonMap = new GsonBuilder (). Create () .fromJson (jsonStr, (new TypeReference () {}). GetType (); printMap (gsonMap); System.out.println ("--jackson -"); ObjectMapper objectMapper = new ObjectMapper (); Map jacksonMap = objectMapper.readValue (jsonStr, new TypeReference () {}); printMap (jacksonMap) } private static void printMap (Map map) {map.forEach ((key, value)-> {System.out.println ("key:" + key + ", value=" + value + ", valueClass=" + value.getClass ());});}}

Running result:

{"aInteger": 1, "aLong": 2}

-fastjson-

Key:aLong,value=2,valueClass=class java.lang.Integer

Key:aInteger,value=1,valueClass=class java.lang.Integer

-gson-

Key:aInteger,value=1.0,valueClass=class java.lang.Double

Key:aLong,value=2.0,valueClass=class java.lang.Double

-jackson-

Key:aInteger,value=1,valueClass=class java.lang.Integer

Key:aLong,value=2,valueClass=class java.lang.Integer

Although the original type of aLong is Long, it is deserialized to Integer type in fastjson and jackson, and mapped to Double type in gson.

Let's look at the serialized json string:

{"aInteger": 1, "aLong": 2}

You will find that JSON does not contain type information, and the deserialized type is Map.class or Map type, when you only know this information, you can not know that the original type of aLong is Long.

So different JSON serialization tools give their own default processing behavior.

When we adjust the value of aLong to beyond the range of (Integer.MAX_VALUE,Long.MAX_VALUE], fastjson and jackson can be resolved to the Long type.

Map dataMap = new HashMap (2); dataMap.put ("aInteger", 1); dataMap.put ("aLong", Long.MAX_VALUE)

Output result:

{"aInteger": 1, "aLong": 9223372036854775807}

-fastjson-

Key:aLong,value=9223372036854775807,valueClass=class java.lang.Long

Key:aInteger,value=1,valueClass=class java.lang.Integer

-gson-

Key:aInteger,value=1.0,valueClass=class java.lang.Double

Key:aLong,value=9.223372036854776E18,valueClass=class java.lang.Double

-jackson-

Key:aInteger,value=1,valueClass=class java.lang.Integer

Key:aLong,value=9223372036854775807,valueClass=class java.lang.Long

We learned roughly that fastjson and jackson select Integer first by default for integer types, select Long beyond the Integer range, and so on.

When we put in the Float type, the results are different:

Map dataMap = new HashMap (2); dataMap.put ("aInteger", 1); dataMap.put ("aFLoat", 0.1F)

Running result:

{"aInteger": 1, "aFLoat": 0.1}

-fastjson-

Key:aInteger,value=1,valueClass=class java.lang.Integer

Key:aFLoat,value=0.1,valueClass=class java.math.BigDecimal

-gson-

Key:aInteger,value=1.0,valueClass=class java.lang.Double

Key:aFLoat,value=0.1,valueClass=class java.lang.Double

-jackson-

Key:aInteger,value=1,valueClass=class java.lang.Integer

Key:aFLoat,value=0.1,valueClass=class java.lang.Double

Float is parsed to BigDecimal in fastjson, and to Double in gson and jackson.

How to deal with the bottom layer, you can follow the anti-sequence method of each framework step by step to get the answer.

Here, take fastjson as an example to simply debug:

Fastjson gets the deserializer of the current type as MapDeserializer through the com.alibaba.fastjson.parser.ParserConfig#getDeserializer method

Execute its deserialization method:

Com.alibaba.fastjson.parser.deserializer.MapDeserializer#deserialze

Parse the Map type through com.alibaba.fastjson.parser.deserializer.MapDeserializer#parseMap.

Because the valueType type of Map is Object, aFloat is parsed using the JavaObjectDeserializer deserializer.

Follow up the lexer.decimalValue and take a look:

Finally, aFloat is parsed to BigDecimal type through com.alibaba.fastjson.parser.JSONScanner#decimalValue.

3. How to write a type into a JSON string in 3. 0

If we can write the original type to the JSON string, we can naturally restore the original type when deserializing.

You can use SerializerFeature.WriteClassName in fastjson

Package json;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.serializer.SerializerFeature;import java.util.HashMap;import java.util.Map;public class JsonDemo {public static void main (String [] args) {Map dataMap = new HashMap (2); dataMap.put ("aInteger", 1); dataMap.put ("aLong", 2L); dataMap.put ("aFloat", 3F); String jsonStr = JSON.toJSONString (dataMap, SerializerFeature.WriteClassName) System.out.println (jsonStr); / / fastjson System.out.println ("- fastjson -"); Map fastMap = JSON.parseObject (jsonStr, new com.alibaba.fastjson.TypeReference () {}); printMap (fastMap) } private static void printMap (Map map) {map.forEach ((key, value)-> {System.out.println ("key:" + key + ", value=" + value + ", valueClass=" + value.getClass ());});}}

Printed result

{"@ type": "java.util.HashMap", "aFloat": 3.0F, "aInteger": 1, "aLong": 2L}

-fastjson-

Key:aLong,value=2,valueClass=class java.lang.Long

Key:aFloat,value=3.0,valueClass=class java.lang.Float

Key:aInteger,value=1,valueClass=class java.lang.Integer

Although this approach can solve the problem, it usually requires serialization and deserialization using the same JSON tool.

For example, the above {"@ type": "java.util.HashMap", "aFloat": 3.0F, "aInteger": 1, "aLong": 2L} deserialization directly using jackson will report an error:

System.out.println ("- jackson -"); ObjectMapper objectMapper = new ObjectMapper (); Map jacksonMap = objectMapper.readValue (jsonStr, new TypeReference () {}); printMap (jacksonMap)

Error content:

-jackson-

Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Unexpected character ('F' (code 70)): was expecting comma to separate Object entries

At [Source: (String) "{" @ type ":" java.util.HashMap "," aFloat ": 3.0F," aInteger ": 1," aLong ": 2L}"; line: 1, column: 43]

At com.fasterxml.jackson.core.JsonParser._constructError (JsonParser.java:2391)

At com.fasterxml.jackson.core.base.ParserMinimalBase._reportError (ParserMinimalBase.java:735)

At com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar (ParserMinimalBase.java:659)

3.1 provide POJO class, beware of Map serialization

It is strongly recommended that you don't be afraid of the trouble and define the POJO class directly.

Not only is it not bound by the JSON framework, but also the other side is very clear when parsing, so it is not easy to make mistakes.

For example, when sending MQ messages at work, many people do not want to define POJO objects, because it is usually troublesome to package, so the data to be transmitted to other systems is defined as Map type, and then parsed downstream according to key, which is a very bad habit.

It is easy to cause inconsistency between upstream and downstream types, resulting in failure when replacing the JSON deserialization tool.

Therefore, when sending MQ messages, it is best to give the corresponding POJO class.

In practical work, there are also students who use JSON serialization to store Map in Redis, and then de-serialize the value of the original Long type into Long, resulting in online BUG (as mentioned earlier, when using fastjson in this case, if the value is less than the maximum value of an integer, it will be deserialized to Integer type, and the overturn will inevitably report an error).

3.2 deserialize custom classes

If the upstream serialization is Map, if the type is verified clearly, we can still customize the POJO class to deserialize.

@ lombok.Datapublic class Data {private Float aFloat; private Integer aInteger;} Map dataMap = new HashMap (2); dataMap.put ("aInteger", 1); dataMap.put ("aFLoat", 0.1F); String jsonStr = JSON.toJSONString (dataMap); Data data = JSON.parseObject (jsonStr, Data.class); System.out.println (data)

Output result:

Data (aFloat=0.1, aInteger=1)

Some students may find it troublesome to define POJO classes, but we can use IDEA plug-ins or online tools to implement JSON strings to generate POJO classes.

Such as the Json2Pojo IDEA plug-in

And some online generation tools:

Https://json2csharp.com/json-to-pojo

Https://www.javainuse.com/pojo

These are all the contents of this article entitled "how to solve the problem of JSON deserializing Long into Integer or Double". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 282

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report