0

I have the following problem:

A team-member changed the sensa/ext js front end and is sending a parmeter with a space instead of an underscore. I don't know the front-end code of the project as well, and this is causing the following error:

Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @org.springframework.web.bind.annotation.RequestParam org.company.project.persistence.enums.DocumentTypeEnum for value 'EXPERT OPINION'; nested exception is java.lang.IllegalArgumentException: No enum constant org.company.project.persistence.enums.DocumentTypeEnum.EXPERT OPINION

I changed a get parameter of the request using fiddler and I saw that the problem is that EXPERT OPINION is being sent instead of EXPERT_OPINION.

Initially, I added a filter and tried changing the get parameter value, but I had to add a wrapper since you cannot modify http requests directly. However, the underlying converter seems to get the parameter value directly from the original http request so this failed.

Then I decided to try making a custom converter. I have made the following class that is instantiated when I run the project, but it is never called to perform the specific conversion:

@Configuration
public class EnumCustomConversionConfiguration {

    @Bean
    public ConversionService getConversionService() {
        ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
        bean.setConverters(getConverters());
        bean.afterPropertiesSet();
        ConversionService object = bean.getObject();
        return object;
    }

    private Set<Converter> getConverters() {
        Set<Converter> converters = new HashSet<Converter>();

        converters.add(new StringToEnumConverter(DocumentTypeEnum.class));

        return converters;
    }

    @SuppressWarnings("rawtypes")
    private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> {

        private final Class<T> enumType;

        public StringToEnumConverter(Class<T> enumType) {

            this.enumType = enumType;
        }

        @SuppressWarnings("unchecked")
        public T convert(String source) {

            checkArg(source);
            return (T) Enum.valueOf(enumType, source.trim());
        }

        private void checkArg(String source) {

            // In the spec, null input is not allowed
            if (source == null) {
                throw new IllegalArgumentException("null source is in allowed");
            }
        }
    }

}
Menelaos
  • 23,508
  • 18
  • 90
  • 155
  • 1
    First it might be a good idea to add your custom converter to the existing ones and not replace them with yours. How do you know it's not called? Is this configuration "declared" somehow (i.e. does spring know about it)? Are you sure your converter replaces space by `_` ? Can't you ask the front-end guy/gal to fix his/her mess? –  Sep 13 '16 at 11:23
  • 1
    See also this question: http://stackoverflow.com/questions/11273443/how-to-configure-spring-conversionservice-with-java-config (that might be your problem) –  Sep 13 '16 at 11:25
  • @RC I put breakpoints inside the `convert` method. The method org.springframework.core.convert.support.StringToEnum.convert is being called which is the default spring one... but not my own in order to introduce the hack. I talked with back-end guys and it turns out I need to rebuild the front-end js code. However this still annoyes me... why isn't my own convert method being called for the specific enum type? – Menelaos Sep 13 '16 at 11:26
  • @RC I tried the fix with adding the name but it didn't make a difference. – Menelaos Sep 13 '16 at 12:02
  • To narrow the issue, I would add a bp in `getConversionService` to see if spring use this configuration –  Sep 13 '16 at 15:04

1 Answers1

1

Did you add it to your Spring MVC configuration?

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "..." })
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addFormatters(FormatterRegistry formatterRegistry) {
        formatterRegistry.addConverter(getMyConverter());
    }

...
Yuri Plevako
  • 311
  • 1
  • 6