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.