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:
<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/>
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.
<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/>
MeuController {
public void delete( List<Long> 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
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<Long> id) { ... }
<input name="id[0]" ...>
<input name="id[1]" ...>
<input name="id[2]" ...>
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) { ... }
<input name="id[0]" ...>
<input name="id[1]" ...>
<input name="id[2]" ...>
Isto aqui também funciona:
public void delete(String[] id) { ... }
<input name="id" ...>
<input name="id" ...>
<input name="id" ...>
Mas isto dá pau:
public void delete(String[] id) { ... }
<input name="id[0]" ...>
<input name="id[1]" ...>
<input name="id[2]" ...>
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[]