Explorar o código

[chg] BigDecimal序列化和反序列化器

wcz %!s(int64=5) %!d(string=hai) anos
pai
achega
323a6b27f4

+ 23 - 14
lift-business-service/src/main/java/cn/com/ty/lift/business/framework/conf/BigDecimalDeserializer.java

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.JsonTokenId;
 import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
+import lombok.extern.slf4j.Slf4j;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -15,6 +16,7 @@ import java.math.BigDecimal;
  * @author wcz
  * @since 2020/4/26
  */
+@Slf4j
 public class BigDecimalDeserializer extends StdScalarDeserializer<BigDecimal> {
 
     public static final BigDecimalDeserializer instance = new BigDecimalDeserializer();
@@ -24,29 +26,36 @@ public class BigDecimalDeserializer extends StdScalarDeserializer<BigDecimal> {
     }
 
     @Override
-    public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
-        switch (p.getCurrentTokenId()) {
+    public BigDecimal deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
+        BigDecimal value;
+        switch (parser.getCurrentTokenId()) {
             case JsonTokenId.ID_NUMBER_INT:
             case JsonTokenId.ID_NUMBER_FLOAT:
-                return p.getDecimalValue().setScale(2, BigDecimal.ROUND_HALF_UP);
+                value = parser.getDecimalValue();
+                break;
             case JsonTokenId.ID_STRING:
-                String text = p.getText().trim();
+                String text = parser.getText().trim();
                 // note: no need to call `coerce` as this is never primitive
                 if (_isEmptyOrTextualNull(text)) {
-                    _verifyNullForScalarCoercion(ctxt, text);
-                    return getNullValue(ctxt).setScale(2, BigDecimal.ROUND_HALF_UP);
+                    _verifyNullForScalarCoercion(context, text);
+                    value = getNullValue(context);
+                    break;
                 }
-                _verifyStringForScalarCoercion(ctxt, text);
+                _verifyStringForScalarCoercion(context, text);
                 try {
-                    return new BigDecimal(text).setScale(2, BigDecimal.ROUND_HALF_UP);
-                } catch (IllegalArgumentException iae) {
+                    value = new BigDecimal(text);
+                    break;
+                } catch (IllegalArgumentException ignore) {
                 }
-                return ((BigDecimal) ctxt.handleWeirdStringValue(_valueClass, text,
-                        "not a valid representation")).setScale(2, BigDecimal.ROUND_HALF_UP);
+                value = ((BigDecimal) context.handleWeirdStringValue(_valueClass, text, "not a valid representation"));
+                break;
             case JsonTokenId.ID_START_ARRAY:
-                return _deserializeFromArray(p, ctxt).setScale(2, BigDecimal.ROUND_HALF_UP);
+                value = _deserializeFromArray(parser, context);
+                break;
+            default:
+                // Otherwise, no can do:
+                value = ((BigDecimal) context.handleUnexpectedToken(_valueClass, parser));
         }
-        // Otherwise, no can do:
-        return ((BigDecimal) ctxt.handleUnexpectedToken(_valueClass, p)).setScale(2, BigDecimal.ROUND_HALF_UP);
+        return value.setScale(2, BigDecimal.ROUND_HALF_UP);
     }
 }

+ 40 - 4
lift-business-service/src/main/java/cn/com/ty/lift/business/framework/conf/BigDecimalSerializer.java

@@ -1,10 +1,16 @@
 package cn.com.ty.lift.business.framework.conf;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.ser.ContextualSerializer;
+import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 
 import java.io.IOException;
+import java.lang.reflect.Type;
 import java.math.BigDecimal;
 import java.util.Objects;
 
@@ -14,14 +20,44 @@ import java.util.Objects;
  * @author wcz
  * @since 2020/4/26
  */
-public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
+public class BigDecimalSerializer extends StdScalarSerializer<BigDecimal> implements ContextualSerializer {
 
     public static final BigDecimalSerializer instance = new BigDecimalSerializer();
 
+    public BigDecimalSerializer() {
+        super(BigDecimal.class);
+    }
+
+    @Override
+    public JsonSerializer<?> createContextual(SerializerProvider prov,
+                                              BeanProperty property) throws JsonMappingException {
+        JsonFormat.Value format = findFormatOverrides(prov, property, handledType());
+        if (format != null) {
+            switch (format.getShape()) {
+                case STRING:
+                    return ToStringSerializer.instance;
+                default:
+            }
+        }
+        return this;
+    }
+
     @Override
-    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider provider) throws IOException {
         if(Objects.nonNull(value)){
             gen.writeNumber(value.setScale(2, BigDecimal.ROUND_HALF_UP));
+        } else {
+            gen.writeNumber(value);
         }
     }
+
+    @Override
+    public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
+        return createSchemaNode("number", true);
+    }
+
+    @Override
+    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
+        visitFloatFormat(visitor, typeHint, JsonParser.NumberType.BIG_DECIMAL);
+    }
 }

+ 3 - 2
lift-business-service/src/main/java/cn/com/ty/lift/business/framework/conf/SystemConfiguration.java

@@ -37,6 +37,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.PostConstruct;
+import java.math.BigDecimal;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.List;
@@ -98,8 +99,8 @@ public class SystemConfiguration {
 
             builder.serializerByType(Long.class, ToStringSerializer.instance);
 
-            //builder.serializerByType(BigDecimal.class, BigDecimalSerializer.instance);
-            //builder.deserializerByType(BigDecimal.class, BigDecimalDeserializer.instance);
+            builder.serializerByType(BigDecimal.class, BigDecimalSerializer.instance);
+            builder.deserializerByType(BigDecimal.class, BigDecimalDeserializer.instance);
         };
     }