Passar array de id para o vRaptor

Pelo que li eu poderia submeter vários campos do formulário com mesmo nome que o vRaptor trata como um array no método do controller. Exemplo:

&lt;input type="checkbox" name="id" value="1" /&gt; <br/> &lt;input type="checkbox" name="id" value="2" /&gt; <br/> &lt;input type="checkbox" name="id" value="3" /&gt; <br/> &lt;input type="checkbox" name="id" value="4" /&gt; <br/>

MeuController { public void delete( long[] id ) { ... } }

Acontece que, quando submeto isto, o argumento é nulo. Se coloco índice no “name” do campo dá IndexOutOfBoundException.

Se mudo o argumento para um List<Long>, e uso o índice nos campos, ai funciona.

&lt;input type="checkbox" name="id[0]" value="1" /&gt; <br/> &lt;input type="checkbox" name="id[1]" value="2" /&gt; <br/> &lt;input type="checkbox" name="id[2]" value="3" /&gt; <br/> &lt;input type="checkbox" name="id[3]" value="4" /&gt; <br/>

MeuController { public void delete( List&lt;Long&gt; id ) { ... } }

Qual deve ser o problema? Onde estou errando?

tenta isso

<input type="checkbox" name="id[]" value="1" /> <br/>  
<input type="checkbox" name="id[]" value="2" /> <br/>  
<input type="checkbox" name="id[]" value="3" /> <br/>  
<input type="checkbox" name="id[]" value="4" /> <br/>  

java.lang.ArrayIndexOutOfBoundsException java.lang.reflect.Array.set(Native Method) ognl.ArrayPropertyAccessor.setProperty(ArrayPropertyAccessor.java:121) ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2225) ognl.ASTProperty.setValueBody(ASTProperty.java:127) ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220) ognl.SimpleNode.setValue(SimpleNode.java:279) ognl.ASTChain.setValueBody(ASTChain.java:227) ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220) ognl.SimpleNode.setValue(SimpleNode.java:279) ognl.Ognl.setValue(Ognl.java:737) ognl.Ognl.setValue(Ognl.java:783) br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.createViaOgnl(OgnlParametersProvider.java:132)

Se o método receber um long[ ].

tem algum motivo forte pra usar array ao inves de List?

usar id[0], id[1], etc e long[] deveria funcionar sem problemas

O motivo forte é que o framework diz suportar.

e suporta, se vc usar direito :wink:

usando os indices e long[] funciona (o array vai ser nulo se vc não selecionar nenhum)

<input type="checkbox" name="id[0]" value="1" /> <br/>  
<input type="checkbox" name="id[1]" value="2" /> <br/>  
<input type="checkbox" name="id[2]" value="3" /> <br/>  
<input type="checkbox" name="id[3]" value="4" /> <br/>  

se tanto faz um List ou um array, use List

Provavelmente vocês atualizaram a documentação, mas havia um trecho que orientava a fazer da maneira que fiz com array e usando índica para listas.

My bad! Na verdade eu tinha visto aqui: http://www.wbotelhos.com.br/2010/12/06/manipulando-listas-com-jquery-e-vraptor-3/

Pelo que falei com o autor, ele explicou que só funciona com array de String e não com array de long, int etc.

talvez seja um problema com primitivos… se usar Long[] pode ser que resolva…

quer abrir um bug para ver isso?

E uma feature que há muito desejo é não precisar passar os índices na hora de submeter o array. Tanto a primeira sugestão do Daniel quanto a do Bruno (igual PHP) serviriam. Ter que calcular esses índices no JQuery ao fazer um form dinâmico é um suplício…

name=“qqerCoisa[]” já funciona, Sergio… o VRaptor substitui pelos índices.

Muito bom! Entendi aí de cima que não tava pronto ainda…

talvez tenha algum bug qto a primitivos…

Long[ ] id
ognl.OgnlException: id [br.com.caelum.vraptor.VRaptorException: Unable to find converter for [Ljava.lang.Long;]

long[ ] id
ognl.OgnlException: id [br.com.caelum.vraptor.VRaptorException: Unable to find converter for [J]

<input name=“id[]” …>

[code]HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.ArrayIndexOutOfBoundsException
java.lang.reflect.Array.set(Native Method)
ognl.ArrayPropertyAccessor.setProperty(ArrayPropertyAccessor.java:121)
ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2225)
ognl.ASTProperty.setValueBody(ASTProperty.java:127)
ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
ognl.SimpleNode.setValue(SimpleNode.java:279)
ognl.ASTChain.setValueBody(ASTChain.java:227)
ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
ognl.SimpleNode.setValue(SimpleNode.java:279)
ognl.Ognl.setValue(Ognl.java:737)
ognl.Ognl.setValue(Ognl.java:783)
br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.createViaOgnl(OgnlParametersProvider.java:132)
br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.createRoot(OgnlParametersProvider.java:108)
br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.getParametersFor(OgnlParametersProvider.java:90)
br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:108)
br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:78)
br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:53)
br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:53)
br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:44)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:53)
br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:53)
br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:53)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:53)
br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
[/code]

Único caso que funcionou:

public void delete(List&lt;Long&gt; id) { ... }

&lt;input name="id[0]" ...&gt; &lt;input name="id[1]" ...&gt; &lt;input name="id[2]" ...&gt;

esse caso não funciona?

public void delete(Long[] id) { ... }  
<input name="id[0]" ...>  
<input name="id[1]" ...>  
<input name="id[2]" ...>  

FUNCIONA!

public void delete(Long[] id) { ... }

&lt;input name="id[0]" ...&gt; &lt;input name="id[1]" ...&gt; &lt;input name="id[2]" ...&gt;

Isto aqui também funciona:

public void delete(String[] id) { ... }

&lt;input name="id" ...&gt; &lt;input name="id" ...&gt; &lt;input name="id" ...&gt;

Mas isto dá pau:

public void delete(String[] id) { ... }

&lt;input name="id[0]" ...&gt; &lt;input name="id[1]" ...&gt; &lt;input name="id[2]" ...&gt;

br.com.caelum.vraptor.VRaptorException: Unable to find converter for java.lang.String

Não seria uma boa ter suporta a lista e array sem precisar setar o índice? Independente do seu tipo (primitivo, wrapper, String)?
Entendo que quando for outro tipo de objeto, ai sim o índice é necessário.

danieldestro, esse caso do String[] foi corrigido, vc está com a última versão do VRaptor? a 3.2.0?

dependendo da sua versão até aquele ArrayIndexOutOfBounds já estaria corrigido.

qto a suportar sem setar o índice, isso já funciona na última versão usando o nome[]