ppb
ppb

Reputation: 2613

JSON field Desrializing to lowercase in Spring Boot

I have a Spring Boot Controller -

@RestController
public class UserController {

   @PostMapping
   @ResponseStatus(CREATED)
   public UserResponse register( @Valid @RequestBody UserRequest userRequest) {
     //return ....
   } 
}

Below is UserRequest.java

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserRequest {

    private String email;
    //other property
}

I am sending below json in request body -

 {
   "email" : "[email protected]",
   //some other fields.
 }

Sometime client send email in uppercase or in camel case so in userRquest I want to change value of email field to lowercase like [email protected] while de serializing to UserRequest Object.

Is there any easy way to do this. Can I introduce my own annotation like @ToLowerCase how I can create my own annotation and use that at field level in UserRequest.

Upvotes: 1

Views: 5848

Answers (3)

DwB
DwB

Reputation: 38290

Jackson will use the setter methods in your class. Perform the conversion to lower case in the setter.

For example

public void setEmail(final String newValue)
{
    email = StringUtils.lowerCase(newValue);
}

StringUtils is an apache commons class.

Upvotes: 4

Montaser Sobaih
Montaser Sobaih

Reputation: 305

You can make a general StringDeserializer and register it in ObjectMapper as shown below:-

StringDeserializer class

public final class StringDeserializer extends StdDeserializer<String> {

    public StringDeserializer() {
        super((Class<String>) null);
    }

    @Override
    public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        JsonToken token = parser.getCurrentToken();

        if (token == JsonToken.VALUE_STRING) {
            String text = parser.getText();
            return text == null ? null : text.toLowerCase().trim();
        }

        return null;
    }
}

JacksonConfiguration class

@Configuration
public class JacksonConfiguration {

    @Autowired
    void mapper(ObjectMapper mapper) {
        mapper.registerModule(initModule());
    }

    private Module initModule() {
        SimpleModule module = new SimpleModule();
        module.addDeserializer(String.class, new StringDeserializer());
        return module;
    }
}

The above code makes jackson deserialize all strings to lowercase and trimmed.

Upvotes: 0

Thomas Fritsch
Thomas Fritsch

Reputation: 10127

There is no easy way just by introducing a new annotation @ToLowerCase, because then you would also need to implement some annotation processor for doing the real conversion work.

But you can achieve your goal in a slightly different way. In your UserRequest class annotate the email property with @JsonDeserialize and specify a converter there.

@JsonDeserialize(converter = ToLowerCaseConverter.class)
private String email;

You need to implement the converter class by yourself, but it is easy by extending it from StdConverter.

public class ToLowerCaseConverter extends StdConverter<String, String> {

    @Override
    public String convert(String value) {
        return value.toLowerCase();
    }
}

Upvotes: 6

Related Questions