IT이야기

Spring 3.0 MVC 바인딩 Enums 대소문자 구분

cyworld 2021. 10. 26. 19:27
반응형

Spring 3.0 MVC 바인딩 Enums 대소문자 구분


이와 같이 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

소문자 홈이 실제로 홈임을 이해하기 위해 열거형 형식 변환기를 사용하는 방법이 있습니까?

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를 만들고 다음과 같이 컨트롤러에 등록하려고 합니다.

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

다음과 같이 모든 Enum에서 작동하는 일반 변환기를 만들 수도 있습니다.

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에서 첫 번째 결과입니다 .


To add to @GaryF's answer, and to address your comment to it, you can declare global custom property editors by injecting them into a custom AnnotationMethodHandlerAdapter. Spring MVC normally registers one of these by default, but you can give it a specially-configured one if you choose, e.g.

<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>

MyPropertyEditorRegistrar is an instance of PropertyEditorRegistrar, which in turns registers custom PropertyEditor objects with Spring.

Simply declaring this should be enough.

ReferenceURL : https://stackoverflow.com/questions/4617099/spring-3-0-mvc-binding-enums-case-sensitive

반응형