1

I am using Spring Boot to write a web service. I have an entity Animal and an enum Kind that can be either Kind.DOG or Kind.CAT. The Animal class contains private Kind kind as one of its instance variables. When I make an HTTP request, I pass in a string value for kind and when the request maps to the header:

@RequestMapping(method=RequestMethod.POST, value="/create") public ResponseEntity<Animal> createAnimal(@RequestBody Animal animal)

I want kind to be internally converted to Kind.DOG/Kind.CAT if I am passed in either "dog" or "cat". Right now, if I pass in DOG or CAT, it works fine but if's lowercase it doesn't. Can someone tell me what to do? I tried the following:

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    dataBinder.registerCustomEditor(Kind.class, new KindEnumConverter());
}

@RequestMapping(method=RequestMethod.POST, value="/create")
public ResponseEntity<Animal> createAnimal(@RequestBody Animal animal)

and

public class KindEnumConverter extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(Kind.valueOf(text.toUpperCase()));
    }

}

but it didn't work.

ion20
  • 577
  • 2
  • 7
  • 19
  • Take a look at the accepted answer from this post: https://stackoverflow.com/questions/39774427/springs-requestparam-with-enum – Rana_S Jun 09 '17 at 17:05
  • I tried both solutions but I think the difference is that their enum is a direct `@RequestParam` but for me, it's an instance of the `@RequestBody`. – ion20 Jun 09 '17 at 17:23
  • Then try looking into this. Same Issue as yours: https://stackoverflow.com/questions/33637427/spring-requestbody-and-enum-value – Rana_S Jun 09 '17 at 18:54

1 Answers1

-1

InitBinder won't work with @RequestBody as per my experience. We use Spring Boot and the way I solved this problem is, I excluded all the jackson related dependencies from spring-boot-starter-web, so that I can use latest jackson.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </exclusion>
    </exclusions>
</dependency>

And then I added the latest jackson dependencies as:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.1</version>
</dependency>

Now that we have the new jackson library we can just set this in the application.properties file: spring.jackson.mapper.accept_case_insensitive_enums=true

In case you use YAML, then:

spring:
  jackson:
    mapper:
      accept_case_insensitive_enums: true

Inspiration: https://stackoverflow.com/a/44217670/1781024

Vikas Prasad
  • 2,361
  • 3
  • 22
  • 33