簡體   English   中英

Spring 3.0 MVC 綁定枚舉區分大小寫

[英]Spring 3.0 MVC binding Enums Case Sensitive

如果我在 Spring 控制器中有一個 RequestMapping 像這樣......

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

而 Product 是一個枚舉。 例如。 產品.首頁

當我請求頁面時,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

有沒有辦法讓枚舉類型轉換器理解小寫的 home 實際上是 Home?

我想保持 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());
} 

從廣義上講,您想創建一個新的 PropertyEditor 來為您進行規范化,然后將其注冊到您的 Controller 中,如下所示:

@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);
}

也可以創建一個通用轉換器,可以像這樣與所有枚舉一起使用:

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 解釋的那樣在全球范圍內

在 Spring Boot 2 中,您可以使用ApplicationConversionService 它提供了一些有用的轉換器,尤其是org.springframework.boot.convert.StringToEnumIgnoringCaseConverterFactory - 負責將字符串值轉換為枚舉實例。 這是我設法找到的最通用的(我們不需要為每個枚舉創建單獨的轉換器/格式化程序)和最簡單的解決方案。

import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class AppWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        ApplicationConversionService.configure(registry);
    }
}

我知道問題是關於 Spring 3 的,但這是在搜索spring mvc enums case insensitive短語時在 google 中的第一個結果。

要添加到@GaryF 的答案,並解決您的評論,您可以通過將全局自定義屬性編輯器注入自定義AnnotationMethodHandlerAdapter來聲明它們。 Spring MVC 通常默認注冊其中之一,但如果您願意,您可以給它一個特殊配置的,例如

<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對象。

簡單地聲明這應該就足夠了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM