springboot jackson cast

1. The springboot controller @ requestmapping method is not so strict in type conversion when receiving parameters. When receiving parameters with digital type, the transmitted string can also be converted normally; Receive parameters with boolean type, and transfer numbers to the corresponding true or false;

2. jackson is used by default when spring boot does parameter deserialization. Therefore, as long as you are familiar with jackson serialization, you can know how to start;

3. Starting with a small demo, first define a simple object Obj, including the cycle attribute of Boolean type and the num attribute of Long type:

public class Obj {

    private Boolean cycle;

    private Long num;

Use jackson for deserialization. The cycle attribute value in the json string is set to numeric 5, the num attribute value is set to string "10", and the deserialization to Obj object is successful. The number 5 is resolved to true, and the string "10" is resolved to number 10. This is the phenomenon that jackson does not have forced conversion by default, which is consistent with the default parameter deserialization of springboot:

public class Test {

    public static void main(String[] args) throws Exception {

        ObjectMapper objectMapper = new ObjectMapper();
        String s = "{\"cycle\": 5, \"num\": \"10\"}";
        Obj obj = objectMapper.readValue(s, Obj.class);



Obj(cycle=true, num=10)

If you want jackson to force type conversion, add a line of configuration, and an error is found during execution. Deserialization fails:

public class Test {

    public static void main(String[] args) throws Exception {

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, false);
        String s = "{\"cycle\": 5, \"num\": \"10\"}";
        Obj obj = objectMapper.readValue(s, Obj.class);



Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot coerce Number (5) for type `java.lang.Boolean` (enable `MapperFeature.ALLOW_COERCION_OF_SCALARS` to allow)
 at [Source: (String)"{"cycle": 5, "num": "10"}"; line: 1, column: 11] (through reference chain: test11.Obj["cycle"])
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1329)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._verifyNumberForScalarCoercion(StdDeserializer.java:857)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseBooleanFromInt(StdDeserializer.java:197)
	at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BooleanDeserializer._parseBoolean(NumberDeserializers.java:231)
	at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BooleanDeserializer.deserialize(NumberDeserializers.java:199)
	at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BooleanDeserializer.deserialize(NumberDeserializers.java:175)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
	at test11.Test11.main(Test11.java:20)

4. Therefore, if you want to perform forced type conversion during parameter deserialization in springboot, you also need to add MapperFeature.ALLOW_COERCION_OF_SCALARS, false configuration. How to configure it? Let's start with the automatic configuration of springboot autoconfig. First, find the org.springframework.boot: spring boot autoconfigure jar package

Then find jackson's autoconfiguration class, JacksonAutoConfiguration

  The reason why this class is loaded when springboot starts is that the classes configured in the META-INF/spring.factories file are automatically loaded when springboot starts, and JacksonAutoConfiguration is configured in this file (as for why springboot automatically loads this file, it is written in the source code, and you can read it if you are interested)

Continue back   JacksonAutoConfiguration class. You can see that this class also contains a static internal class jackson2objectmapperbuildercustomizarconfiguration, and @ EnableConfigurationProperties({JacksonProperties.class}) is configured. The JacksonProperties are imported from the application configuration file and loaded into the properties in JacksonProperties during class initialization:

  The JacksonProperties class uses the @ ConfigurationProperties ID to introduce the corresponding configuration item from the spring.jackson prefix in the application configuration file. The type cast configuration we are concerned about is in the mapper property:

  You can see allow through MapperFeature_ COERCION_ OF_ Scalars is true by default, that is, it does not cast types by default:

  Therefore, if you want to perform forced type conversion when deserializing parameters in springboot, you only need to add the following configuration in the application.yml configuration file to take effect:


Tags: Java Spring Spring Boot

Posted on Thu, 21 Oct 2021 23:39:17 -0400 by stewb