VRAPTOR InterceptionException [ RESOLVIDO ]

5 respostas
jsign

Olá pessoal,
Estou estudando o VRaptor para aplica-lo como solução web num próximo projeto.
Seguindo a apostila FJ28, na página 81 especificamente temos um exemplo aplicado à validações.

if (produto.getPreco() <= 0.0) {
validator.add(new ValidationMessage(
"Preço precisa ser positivo", "produto.preco"));
}

Mas quando o usuário deixa o input text em branco ‘’ a seguinte exception é disparada:

br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: java.lang.NullPointerException
br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)

Apenas quando em branco, quando o valor é 0.0 ou mesmo 0 não dá qualquer problema.

Alguem saberia me informar qual a melhor tratativa?

Segue minha bean e controller:

@Resource
public class ProdutosController{

	private final ProdutoDao dao;
	private final Result result;
	private final Validator validator;

	public ProdutosController(ProdutoDao dao, Result result, Validator validator){
		this.dao = dao;
		this.result = result;
		this.validator = validator;
	}

	public List<Produto> lista() {
		return dao.listaTudo();
	}

	/** @see FORWARD & REDIRECT - FJ28 PAG. 61 **/
	public void adiciona(Produto produto) {
		
		validar(produto);
		validator.onErrorUsePageOf(ProdutosController.class).formulario();
		
		dao.salvar(produto);
		result.redirectTo(this).lista(); 
	}

	public void formulario() {
	}

	public Produto edita(Long id) {
		return dao.buscarPorId(id);
	}

	public void altera(Produto produto) {
		
		validar(produto);
		validator.onErrorUsePageOf(ProdutosController.class).edita(produto.getId());
		
		dao.alterar(produto);
		result.redirectTo(this).lista(); 
	}

	public void remove(Long id) {
		Produto produto	=	dao.buscarPorId(id);
		dao.remover(produto);
		result.redirectTo(this).lista(); 
	}

	private void validar(Produto produto){

		if (produto.getNome() == null || produto.getNome().length() < 3) {
			validator.add(new ValidationMessage("O nome do produto &eacute; obrigat&oacute;rio. Deve ser preenchido com mais de 3 letras.", "produto.nome"));
		}
		if (produto.getDescricao() == null || produto.getDescricao().length() < 15) {
			validator.add(new ValidationMessage("A descri&ccedil;&atilde;o do produto &eacute; obrigat&oacute;rio. Deve ser preenchido com mais de 15 letras.","produto.descricao"));
		}
		
		if (produto.getPreco() <= 0.0 || produto.getPreco() == null) {
			validator.add(new ValidationMessage("O pre&ccedil;o do produto &eacute; obrigat&oacute;rio. Deve ser positivo.", "produto.preco"));
		}
	}

}
@Entity
public class Produto {
	
	@Id 
	@GeneratedValue
	private Long id;
	private String nome;
	private String descricao;
	private Double preco;

        // getters and setters 

}

Aproveitando o mesmo tópico: Alguém sabe como evitar com que a validação dinamica, a partir de annotations nas beans, limpe/reinicie nulo todos os campos do formulário.

... controller ... 

               /** ESTA OPÇÃO NAO REINICIA O FORM **/ 

                if (produto.getNome() == null || produto.getNome().length() < 3) {
			validator.add(new ValidationMessage("nome.obrigatorio", "produto.nome"));
		}
		if (produto.getDescricao() == null || produto.getDescricao().length() < 15 || produto.getDescricao().length() > 40) {
			validator.add(new ValidationMessage("descricao.obrigatoria","produto.descricao"));
		}
		if (produto.getPreco() <= 0.0 || produto.getPreco() == null) {
			validator.add(new ValidationMessage("preco.positivo", "produto.preco"));
		}
		
		/** USANDO VALIDAÇÕES APONTADAS NA BEAN => ESTA UTILIDADE REINICIA OS CAMPOS DO FORMULÁRIO **/

		validator.validate(produto);
...

... bean annotations ...

        @Id 
	@GeneratedValue
	private Long id;
	
	@NotNull
	@Length(min=3)
	private String nome;
	
	@NotNull
	@Length(max=40, min=15)
	private String descricao;
	
	@Length(max=40, min=1)
	@Min(0)
	private Double preco;

...

Obrigado.
Jsign

5 Respostas

G

O problema é que preco é um Double wrapper, e você faz essa comparação:

produto.getPreco() <= 0.0

O Java irá fazer o autoboxing desse objeto e o código ficará algo como:

produto.getPreco().doubleValue() <= 0.0

Sendo assim como getPreco vem nulo, dá um NullPointerException. O correto é você também validar se o objeto é nulo ou usar double primitivo.

[code]produto.getPreco() != null && produto.getPreco() <= 0.0
Lucas_Cavalcanti

se vc não manda nenhum parametro começando com produto o produto vem nulo. Se vc não manda o parâmetro produto.preco, o preço vem nulo, como o garcia falou…

qto a segunda dúvida, pros dados do formulário voltarem preenchidos basta vc preencher os values dos inputs:

<input ... name="produto.nome" value="${produto.nome}"/>
<input ... name="produto.preco" value="${produto.preco}"/>

e assim por diante

jsign

Obrigado Lucas, Garcia.

ficou assim:

... controller metodo validar ....

        private void validar(final Produto produto){
		
		validator.checking(new Validations() {{
			
			that(produto.getNome() != null && produto.getNome().length() >= 3, "produto.nome","nome.obrigatorio");
			
			that(produto.getDescricao() != null && produto.getDescricao().length() <= 40 && produto.getDescricao().length() > 15, "produto.descricao", "descricao.obrigatoria");
			
			that(produto.getPreco() != null && produto.getPreco() > 0.0, "produto.preco", "preco.positivo");
			
			}}
		);
		
		/** [ REFORÇO ] USANDO VALIDAÇÕES APONTADAS NAS BEANS :: VAI QUE NÃO SEJAM AS MESMAS **/
		
                validator.validate(produto);
		
	}

... controller action alterar ....

       public void altera(Produto produto) {

		validar(produto);
		validator.onErrorUsePageOf(ProdutosController.class).edita(produto.getId()); // SO PASSA DAQUI SE ESTVIER TUDO VALIDADO 
		
		dao.alterar(produto);
		result.redirectTo(this).lista(); 
	}

... controller action adiciona ....

       public void adiciona(Produto produto) {
		
		validar(produto);
		validator.onErrorUsePageOf(ProdutosController.class).formulario();
		
		dao.salvar(produto);
		result.redirectTo(this).lista(); 
	}

Acho que me atrapalhei um pouco no momento em que separei o metodo de validação.
Valeu pessoal, tá funcionando.

A segunda dúvida foi resolvida devolvendo o usuário a action edita: validator.onErrorUsePageOf(ProdutosController.class).edita(produto.getId())

[]s
Jsign.

jsign

Vou deixar uma pequena nota antes de fechar o tópico:
Estou gostando muito do framework.
É bem mais fácil de implementar no seu projeto soluções custosas em outros frameworks.

Lucas_Cavalcanti

obrigado pelo feedback =)

qqer dúvida é só falar

Criado 21 de dezembro de 2010
Ultima resposta 21 de dez. de 2010
Respostas 5
Participantes 3