Grails将请求参数绑定到枚举 [英] Grails bind request parameters to enum
问题描述
我的Grails应用程序有大量枚举,如下所示:
My Grails application has a large number of enums that look like this:
public enum Rating {
BEST("be"), GOOD("go"), AVERAGE("av"), BAD("ba"), WORST("wo")
final String id
private RateType(String id) {
this.id = id
}
static public RateType getEnumFromId(String value) {
values().find {it.id == value }
}
}
如果我有一个命令对象,如这个:
If I have a command object such as this:
class MyCommand {
Rating rating
}
我想(例如)自动将具有值wo的请求参数转换为Rating.WORST。
I would like to (for example) automatically convert a request parameter with value "wo" to Rating.WORST.
定义自定义转换器的过程描述为此处(在转换的上下文中字符串到日期)。虽然这个程序工作正常,但我不想为每个我的枚举创建一个实现PropertyEditorSupport的类。有没有更好的选择?
The procedure for defining custom converters is described here (in the context of converting Strings to Dates). Although this procedure works fine, I don't want to have to create a class implementing PropertyEditorSupport for each of my enums. Is there a better alternative?
推荐答案
我找到一个解决方案,我很高兴。
I found a solution I'm pretty happy with.
步骤1:创建PropertyEditorSupport的实现,以将文本转换为/从相关枚举转换
Step 1: Create an implementation of PropertyEditorSupport to convert text to/from the relevant Enum
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:定义一个注册类EnumEditor作为各种枚举类的转换器。要更改可通过id绑定的枚举类列表,只需修改 BINDABLE_ENUMS
Step 2: Define a class that registers EnumEditor as a converter for the various enum classes. To change the list of enum classes that are bindable by id, just modify 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:通过在中定义以下Spring bean,使Spring了解上述注册表:grails-app / conf / spring / resources.grooovy
customPropertyEditorRegistrar(CustomPropertyEditorRegistrar)
这篇关于Grails将请求参数绑定到枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!