Spring 3.0 MVC绑定枚举区分大小写

如果我有一个像这样的Spring控制器RequestMapping …

@RequestMapping(method = RequestMethod.GET, value = "{product}") public ModelAndView getPage(@PathVariable Product product) 

产品是一个枚举。 例如。 Product.Home

当我请求该页面时,mysite.com/home

我明白了

 Unable to convert value "home" from type 'java.lang.String' to type 'domain.model.product.Product'; nested exception is java.lang.IllegalArgumentException: No enum const class domain.model.product.Product.home 

有没有办法让枚举types转换器明白,小写的家居然是家?

我想保持url不区分大小写和我的Java枚举与标准大写字母。

谢谢

 public class ProductEnumConverter extends PropertyEditorSupport { @Override public void setAsText(final String text) throws IllegalArgumentException { setValue(Product.valueOf(WordUtils.capitalizeFully(text.trim()))); } } 

注册它

 <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="domain.model.product.Product" value="domain.infrastructure.ProductEnumConverter"/> </map> </property> </bean> 

添加到需要特殊转换的控制器

 @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Product.class, new ProductEnumConverter()); } 

一般来说,你想创build一个新的PropertyEditor,为你做标准化,然后你在你的控制器中注册这样的:

 @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Product.class, new CaseInsensitivePropertyEditor()); } 

我想你将不得不实现一个Custom PropertyEditor 。

像这样的东西:

 public class ProductEditor extends PropertyEditorSupport{ @Override public void setAsText(final String text){ setValue(Product.valueOf(text.toUpperCase())); } } 

看GaryF的答案如何绑定它

如果你在你的枚举常量中使用小写(这可能不应该,但仍然):

 @Override public void setAsText(final String text){ Product product = null; for(final Product candidate : Product.values()){ if(candidate.name().equalsIgnoreCase(text)){ product = candidate; break; } } setValue(product); } 

也可以创build一个通用的转换器,它可以和所有的Enums一起工作:

 public class CaseInsensitiveConverter<T extends Enum<T>> extends PropertyEditorSupport { private final Class<T> typeParameterClass; public CaseInsensitiveConverter(Class<T> typeParameterClass) { super(); this.typeParameterClass = typeParameterClass; } @Override public void setAsText(final String text) throws IllegalArgumentException { String upper = text.toUpperCase(); // or something more robust T value = T.valueOf(typeParameterClass, upper); setValue(value); } } 

用法:

 @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(MyEnum.class, new CaseInsensitiveConverter<>(MyEnum.class)); } 

或作为skaffman全球解释

要添加到@ GaryF的答案,并解决您的评论,您可以声明全局自定义属性编辑器通过注入到自定义AnnotationMethodHandlerAdapter 。 Spring MVC通常在默认情况下注册其中的一个,但是如果您select的话,您可以给它一个特殊的configuration

 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="propertyEditorRegistrars"> <list> <bean class="com.xyz.MyPropertyEditorRegistrar"/> </list> </property> </bean> </property> </bean> 

MyPropertyEditorRegistrarPropertyEditorRegistrar一个实例,它MyPropertyEditorRegistrar向Spring注册自定义的PropertyEditor对象。

简单地声明这应该是足够的。