3

I have this enum declaration below

public enum FamilyType {
    FIRSTNAME("firstname"),
    LASTNAME("lastname");

    private final String type;

    FamilyType(String type) {
        this.type = type;
    }

    public static FamilyType fromString(String type) {
        for (FamilyType t : FamilyType.values()) {
            if (t.type.equals(type)) {
                return t;
            }
        }
        return converter(type);
    }

    @Deprecated
    private static FamilyType converter(String value) {
        if ("NICKNAME".equalsIgnoreCase(value)) {
            return FIRSTNAME;
        }
        if ("SURENAME".equalsIgnoreCase(value)) {
            return LASTNAME;
        }

        throw new InvalidFileNameException("my-enum", value);
    }
}

and I have a controller endpoint where the delete request holds the FamilyType as Requestparam like the following

public String deleteFamilyType(@PathVariable String userId, @Valid @RequestParam FamilyType familyType) {

while sending from postman familytype=firstname, it works but if sending familytype=nickname then my converter returns

org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:
Failed to convert value of type 'java.lang.String' to required type 'FamilyType';
nested exception is java.lang.IllegalArgumentException: 
No enum constant FamilyType.NICKNAME
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:133)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.
samabcde
  • 6,988
  • 2
  • 25
  • 41
Catalina
  • 663
  • 5
  • 20

1 Answers1

3

Following this tutorial section 3, we can use custom converter to override the default conversion Enum#valueOf.

public class StringToFamilyTypeConverter implements Converter<String, FamilyType> {
    @Override
    public FamilyType convert(String source) {
        if ("NICKNAME".equalsIgnoreCase(source)) {
            return FamilyType.FIRSTNAME;
        }
        if ("SURENAME".equalsIgnoreCase(source)) {
            return FamilyType.LASTNAME;
        }
        return FamilyType.valueOf(source.toUpperCase());
    }
}

And then add the converter to MVC configuration

@Configuration
public class AppConfig implements WebMvcConfigurer {
    // ...
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToFamilyTypeConverter());
    }
    // ...
}
samabcde
  • 6,988
  • 2
  • 25
  • 41
  • `MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type` – Catalina Apr 22 '21 at 13:30
  • Can you edit your post to include the full stacktrace? – samabcde Apr 22 '21 at 13:34
  • it works with @requestBody so if the enum value is part of body but not in case of requestparam weired, its not even commes to convert method in class StringToFamilyTypeConverter – Catalina Apr 22 '21 at 13:43
  • I think there is other configuration interfere, as the default behavior is case sensitive, but you can convert with lower case. I can't help much without the full source. – samabcde Apr 22 '21 at 13:45
  • how to do that plz – Catalina Apr 22 '21 at 13:46
  • So what addition step have you done? I am just interested. – samabcde Apr 22 '21 at 13:54
  • there was ` webBinder.registerCustomEditor(FamilyType.class, new CaseInsensitiveConverter(FamilyType.class));` in my initBinder so i removed it and worked, what do you think about it? – Catalina Apr 22 '21 at 13:56
  • Thanks, everything make sense to me now, I suggest you also include the `initBinder` method in the post as this is one of the cause of the problem. – samabcde Apr 22 '21 at 14:00