2009-11-20 5 views
10

내 Grails 애플리케이션은 다음과 같이 열거의 큰 숫자를이 열거 형 바인딩 (예를 들어) 값이 "wo"인 요청 매개 변수를 Rating.WORST로 자동 변환합니다.Grails는 요청 매개 변수는

사용자 지정 변환기를 정의하는 절차는 here (문자열을 날짜로 변환하는 컨텍스트에서 설명)입니다. 이 절차는 정상적으로 작동하지만 내 열거 형마다 PropertyEditorSupport를 구현하는 클래스를 생성하지 않아도됩니다. 더 나은 대안이 있습니까?

답변

11

나는 꽤 행복 해요 해결책을 발견했다.

1 단계 : 다양한 열거 클래스 변환기로 EnumEditor을 등록하는 클래스를 정의 :는 관련 열거

로/
public class EnumEditor extends PropertyEditorSupport { 

    private Class<? extends Enum<?>> clazz 

    public EnumEditor(Class<? extends Enum<?>> clazz) { 
     this.clazz = clazz 
    } 

    public String getAsText() { 
     return value?.id 
    } 

    public void setAsText(String text) { 
     value = clazz.getEnumFromId(text) 
    } 
} 

2 단계를 텍스트로 변환하는 PropertyEditorSupport의 구현을 작성합니다. ID로 바인딩입니다 열거 클래스의 목록을 변경하려면, 바로 수정 BINDABLE_ENUMS

public class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar { 

    private static final String REQUIRED_METHOD_NAME = 'getEnumFromId' 

    // Add any enums that you want to bind to by ID into this list 
    private static final BINDABLE_ENUMS = [Rating, SomeOtherEnum, SomeOtherEnum2] 

    public void registerCustomEditors(PropertyEditorRegistry registry) {    

     BINDABLE_ENUMS.each {enumClass -> 
      registerEnum(registry, enumClass) 
     } 
    } 

    /** 
    * Register an enum to be bound by ID from a request parameter 
    * @param registry Registry of types eligible for data binding 
    * @param enumClass Class of the enum 
    */ 
    private registerEnum(PropertyEditorRegistry registry, Class<? extends Enum<?>> enumClass) { 

     boolean hasRequiredMethod = enumClass.metaClass.methods.any {MetaMethod method -> 
      method.isStatic() && method.name == REQUIRED_METHOD_NAME && method.parameterTypes.size() == 1 
     } 

     if (!hasRequiredMethod) { 
      throw new MissingMethodException(REQUIRED_METHOD_NAME, enumClass, [String].toArray()) 
     } 
     registry.registerCustomEditor(enumClass, new EnumEditor(enumClass)) 
    } 
} 

3 단계 : 레지스트리의 봄을 인식 위

customPropertyEditorRegistrar(CustomPropertyEditorRegistrar) 
+0

잘 했어! 나는 같은 문제로 어려움을 겪고있다. Grails의 표준 부분이 아닌 이유는 무엇입니까? 요청 매개 변수를 도메인/명령 객체에 바인딩하는 Grails의 지원은 정말 끔찍합니다. – mcv

+3

Grails는 enum에 대한 바인딩 요청 파라미터를 지원하지만, 기본값은 이름으로 바인딩됩니다. 위와 같이 다른 enum 속성 (예 : id)을 사용하여 바인딩하려는 경우 직접 바인딩을 정의해야합니다 –

10

그래서 기본 Databinding은 열거 형의 별도로 정의 된 속성이 아니라 열거 형 이름에 바인딩됩니다. 다음 중 하나를 수행 할 수 있습니다 create your own PropertyEditor 당신이 언급 또는 수행 한 같은 해결 방법이 유사 :

class MyCommand { 
String ratingId 
    Rating getRating() { 
    return Rating.getEnumFromId(this.ratingId) 
    } 
    static constraints = { 
    ratingId(validator:{val, obj -> Rating.getEnumFromId(val) != null }) 
    } 
} 
+0

최고 grails-app/conf/spring/resources.grooovy에 다음 Spring 빈을 정의하여 확인 해결 방법 콜린! –