You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Miguel <mi...@almeida.at> on 2011/05/17 12:19:24 UTC

Type conversion of List - how does one do it?

I've always struggled with type conversion of lists and I'd appreciate a
more experienced brain to help me out.

Consider the following multiple select box:

<s:select 	multiple="true" name="users.id" list="users" 	listKey="id"
listValue="username"	value="%{centre.users.{user.id}}" />

As per the documentation, "name your element people.name and the
framework will understand that it should create a new Person object for
each selected item and set its name accordingly."

This works correctly, without even needing an
MyAction-conversion.properties file if my action has:

private List<UserImpl> users;

However, because I usually work with interfaces (and Spring-inject my
dependencies), to have my action implementation-agnostic I want to have.

private List<User> users;

where User is an interface and UserImpl implements User.

However, as soon as the List (and getter/setters) are changed to use
User, the type conversion no longer works, yielding:

2011-05-17 11:17:13,554 WARN  [CommonsLogger.java:60] : Error setting
expression 'users.id' with value '[Ljava.lang.String;@13d344e7'
ognl.OgnlException: Error converting given String values for Collection.
[org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'com.itclinical.iwrs.model.User': Could not resolve
matching constructor (hint: specify index/type/name arguments for simple
parameters to avoid type ambiguities)]

This happens even if I have a UserEditAction-conversion.properties with:
#KeyProperty_users=id
#Element_users=iw.persist.model.UserImpl
#CreateIfNull_users=true


So, how can one use the automatic type conversion when your list is
defined for an interface?

Thank you in advance,

Miguel Almeida

Re: Type conversion of List - how does one do it?

Posted by Miguel <mi...@almeida.at>.

On Tue, 2011-05-17 at 14:42 -0700, Jeffrey Black wrote:

> Hey there Miguel.
>  
> Have a look here:
>  
> http://struts.apache.org/2.0.14/docs/type-conversion.html#TypeConversion-GenericsandErasure


Thanks Jb. In my case a possible solution is to remove the generic
reference to the list (ie, changing List<MyInterface> to List). 

This isn't usually necessary because Spring automatically injects the
implementations in non-collection objects (ie, a private SomeInterface
property is automatically injected with whichever bean we defined for
SomeInterface in Spring), but doesn't work with collections (or I
haven't figured out how to configure that in Spring).

Given that an implementation-agnostic solution is preferable, the advice
on the page "instantiate the target implementation first (eg. in a
prepare method) or substitute in an implementation." is not, in my
opinion, preferable.


Miguel

Re: Type conversion of List - how does one do it?

Posted by Jeffrey Black <je...@yahoo.com>.
Hey there Miguel.
 
Have a look here:
 
http://struts.apache.org/2.0.14/docs/type-conversion.html#TypeConversion-GenericsandErasure
 
Best,
 
jb

From: Miguel <mi...@almeida.at>
To: user@struts.apache.org
Sent: Tuesday, May 17, 2011 5:19 AM
Subject: Type conversion of List<SomeInterface> - how does one do it?

I've always struggled with type conversion of lists and I'd appreciate a
more experienced brain to help me out.

Consider the following multiple select box:

<s:select     multiple="true" name="users.id" list="users"     listKey="id"
listValue="username"    value="%{centre.users.{user.id}}" />

As per the documentation, "name your element people.name and the
framework will understand that it should create a new Person object for
each selected item and set its name accordingly."

This works correctly, without even needing an
MyAction-conversion.properties file if my action has:

private List<UserImpl> users;

However, because I usually work with interfaces (and Spring-inject my
dependencies), to have my action implementation-agnostic I want to have.

private List<User> users;

where User is an interface and UserImpl implements User.

However, as soon as the List (and getter/setters) are changed to use
User, the type conversion no longer works, yielding:

2011-05-17 11:17:13,554 WARN  [CommonsLogger.java:60] : Error setting
expression 'users.id' with value '[Ljava.lang.String;@13d344e7'
ognl.OgnlException: Error converting given String values for Collection.
[org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'com.itclinical.iwrs.model.User': Could not resolve
matching constructor (hint: specify index/type/name arguments for simple
parameters to avoid type ambiguities)]

This happens even if I have a UserEditAction-conversion.properties with:
#KeyProperty_users=id
#Element_users=iw.persist.model.UserImpl
#CreateIfNull_users=true


So, how can one use the automatic type conversion when your list is
defined for an interface?

Thank you in advance,

Miguel Almeida