Grails link listing assembly

In my grails application, I have this enumeration:

public enum RelationshipStatus{ Single_Never_Married, Separated, Divorced, Widowed; } 

I defined this command object:

 class MyCommand { List<RelationshipStatus> relationshipStatuses } 

which I use in one of my controller actions

 def myAction = {MyCommand myCommand -> } 

when I submit a request for this action with parameters

 user.relationshipStatuses=Separated&user.relationshipStatuses=Divorced 

I expect myCommand.relationshipStatuses to contain RelationshipStatus.Separated and RelationshipStatus.Divorced , but it's actually null.

I understand that Grails automatically performs a param -> enum parameter conversion based on the enumeration name. It's just that this is not the case, I tried to define a property editor that does this conversion:

 class RelationshipStatusEnumEditor extends PropertyEditorSupport { public String getAsText() { value.name() } public void setAsText(String text) { RelationshipStatus.valueOf(text) } } 

I registered this editor with Grails / Spring and tried again, but the result was the same. Can I associate query parameters with Collection from Enum?

+1
source share
2 answers

Using the database introduced in Grails 2.3, I came up with the following solution for converting query parameters to enumeration collection. For example, given these listings

 enum Gender { MALE, FEMALE } enum Season { SPRING, SUMMER, AUTUMN, WINTER } 

and this command object

 class MyCommand { Collection<Gender> genders Collection<Season> seasons } 

and suppose we want to convert strings like "MALE,FEMALE" and "SPRING,SUMMER,WINTER" to the corresponding collection of enumerations. First, provide an implementation of FormattedValueConverter that does the conversion

 class EnumCollectionConverter implements FormattedValueConverter { /** * To make other enums bindable, just add them to this list */ private static final List<Class<Enum>> convertableEnums = [Gender, Season] @Override Object convert(value, String format) { Class<Enum> targetEnumClass = convertableEnums.find { it.simpleName == format } if (targetEnumClass) { List<String> enumConstantNames = value.toString().tokenize(',') return enumConstantNames.collect { targetEnumClass.valueOf(it) } } value } @Override Class<?> getTargetType() { // this class converts to a Collection<T extends Enum<T>> but the return value // of this method can't be any more specific than Collection due to type erasure Collection } } 

Then register the EnumCollectionConverter as a Spring bean in resources.groovy - it doesn't matter which name you choose for the bean. Then, to use the class above to convert a comma-separated string to a num collection, annotate the corresponding properties with

 class MyCommand { @BindingFormat('Gender') Collection<Gender> genders @BindingFormat('Season') Collection<Season> seasons } 

The value passed to @BindingFormat must be a simple name of the enumeration type that will be stored in the associated collection.

+1
source

As I know, grails does not populate the default list properties if it is empty. Only if it already exists and element indices are passed.

Try defining this property as:

 import org.apache.commons.collections.ListUtils import org.apache.commons.collections.Factory class MyCommand { List<RelationshipStatus> relationshipStatuses = ListUtils.lazyList([],{new RelationshipStatus()} as Factory) } 

and enter the parameters as:

 user.relationshipStatuses[0]=Separated&user.relationshipStatuses[1]=Divorced 
0
source

Source: https://habr.com/ru/post/1369560/


All Articles