9

@JsonCreator not deserialising @RequestParam of type enum

I am working on a Spring application where the controller is receiving list of request params that Spring is binding to a wrapper object. One of the params is of type enum where I am receiving it by some property name.

Endpoint example: http://localhost:8080/searchCustomers?lastName=Smith&country=Netherlands

@RequestMapping(value = "/search/customers", method = RequestMethod.GET)
public CustomerList searchCustomers(@Valid CustomerSearchCriteria searchCriteria)

public class CustomerSearchCriteria {

    private String lastName;
    private Country country;
}

public enum Country {

    GB("United Kingdom"),
    NL("Netherlands")

    private String countryName;

    Country(String countryName) {
        countryName = countryName;
    }

    @JsonCreator
    public static Country fromCountryName(String countryName) {

        for(Country country : Country.values()) {

            if(country.getCountryName().equalsIgnoreCase(countryName)) {

                return country;
            }
        }
        return null;
    }

    @JsonValue
    public String toCountryName() {

        return countryName;
    } 
}

I am expecting Spring to bind enum Country.Netherlands to CustomerSearchCriteria.country but its not doing it so. I tried similar annotations with @RequestBody and that works fine, so I am guessing he Spring binding is ignoring @JsonCreator.

Any helpful tips would be appreciated.

Dev
  • 195
  • 10
  • Sorry for the confusion, the Json body maps correctly when I use it as @RequestBody, but when I pass the request params (like in the mentioned endpoint) thats when the enum does not bind to CustomerSearchCriteria. Tried both country and countryName – Dev Feb 05 '19 at 09:45
  • 5
    because you want to it by yourself that because you need to use initbinder annotation and also create registerCustomEditor , custom editor which is extends PropertyEditorSupport and then convert it there and bind in initbinder method so checkout link https://www.devglan.com/spring-boot/enums-as-request-parameters-in-spring-boot-rest – Mithat Konuk Feb 05 '19 at 11:53
  • Thats exactly how I ended up solving this i.e. by registering custom editor to convert Country.Netherlands to Country.NL and removing JsonCreator altogether. Thanks anyway. – Dev Feb 05 '19 at 13:36

1 Answers1

1

Here is the code that is behind @Mithat Konuk comment.

Put in your controller something like:

import java.beans.PropertyEditorSupport;

@RestController
public class CountryController {

// your controller methods
// ...

  public class CountryConverter extends PropertyEditorSupport {
    public void setAsText(final String text) throws IllegalArgumentException {
      setValue(Country.fromCountryName(text));
    }
  }

  @InitBinder
  public void initBinder(final WebDataBinder webdataBinder) {
    webdataBinder.registerCustomEditor(Country.class, new CountryConverter());
  }
}

More information ca be found here: https://www.devglan.com/spring-boot/enums-as-request-parameters-in-spring-boot-rest.

gawi
  • 2,843
  • 4
  • 29
  • 44
  • for more info about init binder [Link] (https://stackoverflow.com/questions/5211323/what-is-the-purpose-of-init-binder-in-spring-mvc) – Aravind Mar 09 '22 at 06:29