Search code examples
spring-bootjacksonjackson-databind

Prevent Primitive To String Conversion in SpringBoot / Jackson


We have written a Springboot Rest Service, it internally uses Jackson for Serialisation / deserialisation of Json input / output of Rest APIs.

We do not want type conversion of primitives to / from String for API input / output.

We have disabled String to Primitive conversion using

spring.jackson.mapper.allow-coercion-of-scalars=false

But Primitive to String conversion is still being allowed.

e.g.

"name": 123,

from API is still deserialised to "123", Java data type of name is String here.

We have gone through Customize the Jackson ObjectMapper section of Spring Docs and does not look like there is anything in those enums that can be used.

Is there a way to achieve this without writing a custom ObjectMapper / Deserializer?


Solution

  • We did not find any config property that achieves this, finally went with the solution posted by Michał Ziober.

    package xyz;
    
    import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.core.JsonToken;
    
    import java.io.IOException;
    
    public class StrictStringDeserializer extends StringDeserializer {
        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            JsonToken token = p.currentToken();
            if (token.isBoolean()
                    || token.isNumeric()
                    || !token.toString().equalsIgnoreCase("VALUE_STRING")) {
                ctxt.reportInputMismatch(String.class, "%s is not a `String` value!", token.toString());
                return null;
            }
            return super.deserialize(p, ctxt);
        }
    }
    
    
    
    

    POJO Class

    public class XyzAbc {
    
        // ...
        @JsonDeserialize(using = StrictStringDeserializer.class)
        private String name;
        // ...
    }