VRaptor - InvalidParameterException - String para int

Boa noite pessoal.
Eu procurei aqui no forum e na net alguma informação sobre isso, mas não achei.

O problema eu creio que seja bem simples: erro de conversão.

No meu objeto tenho uma propriedade int. Caso eu digite no meu campo de formulário letras, recebo a exceção:
br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target…

Como eu trato essa exceção? Eu coloco um javascript para tentar evitar que o usuário digite letras, mas gostaria de validar no servidor.

Valeu

Oi, Romulinho. O lance é que o VRaptor já tem conversores para os tipos primitivos (no caso o int), então quando ele detecta que o tipo do seu parâmetro é int, ele vai tentar converter (literamente chamando Integer.valueOf(PARAMETRO_REQUEST)). O JSF tmb funciona assim, e muitos outros frameworks.

Você mesmo matou a charada: validar com javascript. Mas se você precisa validar no servidor, a alternativa mais simples que vejo é alterar o tipo do parâmetro para String e você mesmo tentar converter para int na lógica do seu Controller, e se for um número inválido você teria controle sobre a Exception.

Valeu pela resposta bob_sponja.

Eu entendo que o problema é de conversão mesmo, mas no JSF por exemplo, eu tenho como mudar a mensagem de erro em caso de problema de conversão.
Mas blz, vou ver se resolvo com um interceptor ou então fazer como você disse, só que isso é custos se eu começar a espalhar pelo sistema

Valeu

É, não é uma coisa bacana de se espalhar pelo sistema (aliás, nenhuma dívida técnica é boa de se espalhar pelo sistema =P hehehe). Mas se o lance for somente a mensagem exibida, é só adicionar a chave “is_not_a_valid_integer” no seu arquivo de mensagens que o Converter puxa de lá.

Não tinha passado por essa necessidade, mas dando uma olhada na documentação, talvez vc consiga um ajuste fino interagindo antes do interceptor ParametersInstantiatorInterceptor. De qualquer forma, o Lucas Cavalcanti ou o jj-garcia poderiam te dar um direcionamento mais preciso.

Romulinho, depois dessa discussão fui aprofundar no funcionamento do VRaptor. Vi que o interceptor dele que instancia e converte os parâmetros do request coloca os erros dentro do Validator, e mesmo que tenha dado erro de conversão a lógica do seu controller é executada.

No validador é adicionado um Message com uma category e uma message. O valor da category é o nome do parâmetro que teve erro de conversão. Então eu fiz o seguinte:

  • Sobrescrevi o validador do VRaptor e criei um método “hasCategory(String)”:
@Component
@RequestScoped
public class ValidadorCustomizado extends DefaultValidator {

	public ValidadorCustomizado(Result result, ValidationViewsFactory factory, Outjector outjector, Proxifier proxifier,
			List<BeanValidator> beanValidators, Localization localization) {
		super(result, factory, outjector, proxifier, beanValidators, localization);
	}
	
	public boolean hasCategory(String categoria) {
		for (Message mensagem : getErrors()) {
			if (mensagem.getCategory().equals(categoria)) {
				return true;
			}
		}
		
		return false;
	}

}
  • E na lógica executada pude verificar se houve erro para algum parâmetro:
@Resource
public class TesteController {

    private final Result resultado;
    private final ValidadorCustomizado validador;

    public TesteController(Result resultado, ValidadorCustomizado validador) {
        this.resultado = resultado;
        this.validador = validador;
    }
	
    public void erroConversao(Integer numeroInvalido) {
        // Aqui eu passo o nome do parâmetro para verificar se há erro nele
        if (validador.hasCategory("numeroInvalido")) {
            for (Message message : validador.getErrors()) {
                System.out.println(message.getCategory());

                // Essa mensagem é configurada no arquivo de mensagens
                System.out.println(message.getMessage());
            }
        }
		
        validador.onErrorRedirectTo(this).erroConversao(-99);
        resultado.include("mensagem", "Número inválido => "+numeroInvalido);
    }
	
}

Bom, sabendo disso você pode customizar um validador para melhor atender às suas necessidades. Não sei se já resolveu seu problema, mas de qualquer forma pode servir para outro também.