No meu controller, existe a action para a qual o form é submetido:
E o meu DTO tem o seguinte construtor:
Tudo funciona perfeitamente se eu marco todos os checkboxes na tela, pois aí o meu objeto é populado no controller. O problema acontece quando o usuário deixa de marcar pelo menos um dos checkboxes, pois aí todo o objeto fica nulo.
Tem algum modo de fazer com que o VRaptor popule o meu DTO mesmo que o usuário não marque todos os checkboxes?
Sinto lhe dizer, mas isso não é bem um problema do VRaptor, os checkbox, quando desmarcados, são ignorados na requisição.
Ou seja, o seu browser simplesmente não envia um valor nulo ou falso para esses names que estiverem desmarcados.
O que você pode fazer:
1 - Sobrecarregar os construtores da classe para que você tenha todas as combinações possíveis desses checkboxes.
2 - Fazer setters para os atributos e setar false como default.
3 - Acredito que com um interceptor antes do ParameterInstantiatorInterceptor, aonde você inclui de forma genérica os valores dos checkboxes para false. (Basicamente, se você tem um boolean e o mesmo não vier na requisição, você coloca na requisição)
4 - Fazer o browser enviar false quando os checks estiverem desmarcados, com JavaScript.
O meu ponto de vista sobre cada solução:
1 - Vai ficar difícil de manter, vai ficar complexo. Mas o seu objeto pode continuar sendo imutável.
2 - Talvez a melhor solução. Simples, fácil de manter, mas o seu objeto deixa de ser imutável.
3 - Complexo, pode te trazer mais dores de cabeça do que tranquilidade, não sei se compensa.
4 - Esse é interessante caso você faça o envio desse form com ajax, aonde é mais tranquilo mudar os dados da requisição.
EU, uso o de número 4, pois todos meus forms são enviados com ajax e por uma única função que tem essa responsabilidade. Nesse caso compensa.
Deste modo, quando o checkbox não está marcado, o valor do hidden é enviado. Quando ele é marcado, o valor do checkbox é enviado.
Está funcionando para mim
Discordo. Com JavaScript (e jQuery) você consegue fazer um único evento tratar isso de uma forma melhor. Inclusive, até usando algo parecido com essa sua abordagem. Mas ai vai de cada um.