Dúvidas pontuais no Tutorial do vRaptor3

114 respostas
D

Lucas Cavalcanti:
Veja se você está usando as convenções direitinho:

a o método:

@Resource
public class ClienteController {
   public void lista() {...}  
}

Oi Lucas, tudo blz?! :wink:

Comecei a estudar o vRaptor e o  Tut da Caelum!

Antes de entrar no Validations, fiquei tão ansioso (e entusiasmado 8) ) com o Frame, q eu decidi logo comentOut as Annotations na Entidade Produto e improvisar +/- 1 mock na DAO p/ ver a página lista.jsp funcionando.

Além disso, tive q adicionar o import da .TLD Core da JSTL. Porém, agora apresenta o seguinte erro: 

br.com.caelum.vraptor.view.ResultException: javax.servlet.ServletException: javax/el/ValueExpression

br.com.caelum.vraptor.view.DefaultPageResult.forward(DefaultPageResult.java:69)

br.com.caelum.vraptor.extra.ForwardToDefaultViewInterceptor.intercept(ForwardToDefaultViewInterceptor.java:59)

br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)

br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)

…”

Ah, no Tutorial está deste jeito:

public List<Produto> lista() { return dao.listaTodos(); }
Afinal, Qual é a maneira (convenção) correta??! :roll:
Thnx in advance,

114 Respostas

Lucas_Cavalcanti

se está dando javax/el/ValueExpression é pq vc está (ou não) com o standard.jar ou jstl.jar no WEB-INF/lib… talvez vc tenha que colocar (ou tirar) esses jars

qto à convenção, você usa o retorno se quiser que o VRaptor jogue o retorno pra view automaticamente… nesse caso o nome do atributo jogado seria produtoList.

se não quiser usar o retorno, vc pode usar o

result.include("produtos", produtos);
D

(Obs.: na pág. ‘form.jsp’ eu adicionei o import jstl/core e a tag <c:url (colocada no atrubuto action=’’’) passou a funcionar adequadamente. Então, desta forma, achei q não iria ter problemas com a c:forEach em ‘lista.jsp’ :shock: )

Mas, realmente na aplicação/projeto disponibilizada estava faltando o ‘standard.jar’. Adicionei-o; acabei tendo alguns problemas de ‘deferredExpression’ e acabei adicionando tb o ‘jstl.jar’ (da mesma versão do meu standard.jar) no lugar dos 2: ‘jstl-api-1.2.jar’ e ‘jstl-impl-1.2.jar’ (q creio ser útil para v6 q estão desenvolvendo o FrameWork) tendo em vista q tive q alterar a especificação da Aplicação de JavaWeb 2.5 para 2.4, pois só posso usar TomCat 5.5 => Valews mesmo pela dica!! :wink:

Ah, tenho + 1 dúvida. Poderia trocar toda a Convenção ‘form’ por, por exemplo, ‘manter’??! (Ou ‘form’ é 1 “convenção interna” do vRaptor??)
grato,

Derlon

Lucas_Cavalcanti

vc diz o nome do método? Você pode usar o nome que quiser… se mas se vc tiver o método ProdutoController.manter() ele vai responder à URI /produto/manter
e vai pra jsp /WEB-INF/jsp/produto/manter.jsp

D
Ah, perfeito!! O vRaptor é extremamente CoC mesmo! :thumbup: Sakei!! 8) Agora estou tentando utililizar a Validação Clássica da seguinte forma:
public void adiciona(final Produto produto) {
		if (produto.getNome() == null) 
			validator.add(new ValidationMessage("erro","nome.vazio"));
		if (produto.getPreco() < 1) 
			validator.add(new ValidationMessage("erro","preco.invalido"));
		validator.onErrorUse(Results.page()).of(ProdutosController.class).form();
		
		dao.adiciona(produto);
		result.redirectTo(ProdutosController.class).lista();
	}
e o Console apresenta: " . . 14:58:50,360 DEBUG [JstlLocalization ] couldn't find message bundle, creating an empty one .. 14:58:50,376 DEBUG [DefaultStaticContentHandler] Deferring request to container: /OnLineStore/WEB-INF/jsp/produtos/form.jsp 14:58:50,376 DEBUG [VRaptor ] VRaptor ended the request " Por gentileza, me confirme: seria 1 mito o q dizem q quando usar o estilo clássico não precisar adicionar 1 arquivo messages.properties??! :roll: Ah, e em outro tópico vc falou
Adicione o jar hamcrest-all.jar que está no zip do vraptor na pasta lib/optional, no seu classpath
Eu não pude encontrar! :( Em todo caso, onde tem disponível para DownLoad??! E só + 1 duvidinha: no vRaptor existe alguma forma de fazer Valicação de forma centralizada (bem ao estilo do Seam), ou seja, em 1 só local definir a Validação para q seja gerada tanto Server-side como Client-side??! :mrgreen:
Lucas_Cavalcanti

esse erro do bundle q dá é só log… vc pode ignorar ele

http://tinyurl.com/vr3dl vraptor-3.1.1.zip

derlon:

E só + 1 duvidinha: no vRaptor existe alguma forma de fazer Valicação de forma centralizada (bem ao estilo do Seam), ou seja, em 1 só local definir a Validação para q seja gerada tanto Server-side como Client-side??! :mrgreen:

não tem nada pronto nesse sentido ainda…

D

Agora voltou a funfar novamente! :wink:

Então apenas me confirme: seu eu usar o HamCrest, sou “obrigado” a adicionar o messages.properties no meu default src??!
Bem, continuando a minha saga do tutorial do vRaptor3: estou tentando fazer a Validação Estilo Fluente, porém adicionando no messages o seguinte:
greater_than = maior que
required_field = {0} é um Campo Obrigatório

Form Produtos

produto.nome=Nome
produto.preco=Preço

No método da Controller a seguinte validação:

validator.checking(new Validations() {{ that(!(produto.getNome().isEmpty() ), "Preenchimento Obrigatório", "required_field", "produto.nome"); that(produto.getPreco() > 0, "produto.preco", "greater_than", "Valor Inválido"); }}); acabo obtendo na Página as Mensagens da seguinte forma:
* Preenchimento Obrigatório produto.nome é um Campo Obrigatório
* produto.preco maior que
Ou seja, como faço para passar o Nome do Campo como parâmetro para a ‘Msg de Campo de Preenchimento Obrigatório’ de forma adequada??

Lucas Cavalcanti:

derlon:

E só + 1 duvidinha: no vRaptor existe alguma forma de fazer Valicação de forma centralizada (bem ao estilo do Seam), ou seja, em 1 só local definir a Validação para q seja gerada tanto Server-side como Client-side??! :mrgreen:

não tem nada pronto nesse sentido ainda…

E neste caso você saberia dizer se eu poderia usar/adotar o plugIn Validator da Lib Commons (da Apache; assim como fazemos no Struts1.x)??

Lucas_Cavalcanti

Não sei se obrigado, mas é recomendável fazer isso

tente colocar nas validações:

greater_than = deve ser maior que {0}
required_field = {0} é um Campo Obrigatório
# Form Produtos
produto.nome=Nome
produto.preco=Preço

No Controller:

validator.checking(new Validations() {{
			that(!(produto.getNome().isEmpty() ), "produto.nome", "required_field", "Nome");
			that(produto.getPreco() > 0, "produto.preco", "greater_than", "0");
		}});

derlon:

E neste caso você saberia dizer se eu poderia usar/adorar o plugIn Validator da Lib Commons (da Apache; assim como fazemos no Struts1.x)??

Nunca tentei fazer isso… mas teoricamente vc pode usar esse plugin sim…

D

Lucas Cavalcanti :
No Controller:

validator.checking(new Validations() {{ that(!(produto.getNome().isEmpty() ), "produto.nome", "required_field", "Nome"); ...


Vc sugeriu passar a String [color=blue]“Nome”[/color] no 4° parâmetro: isso não violaria o princípio da Internacionalização??
Bem, relembrando q estou seguindo o exemplo do tutorial, a JSP está assim:

<li>${error.category} ${error.message}</li> Considerando passar uma [color=red]String vazia[/color] no 2° parâmetro (o da Categoria de Erro) e tb no .properties fiz as seguintes alterações:
greater_than = {0} maior que {1}!
produto_nome=Nome

e no Controller:

that(!(produto.getNome().isEmpty() ), "", "required_field", "produto_nome");
			that(produto.getPreco() > 0, "", "greater_than", new String[]{"produto.preco", "0"});

acabo obtendo a seguinte (validação gerada):
* produto_nome é um Campo Obrigatório
* produto.preco maior que 0!

Ou seja, “o vRaptor” não está substituindo as chaves de Nome de Campo pelo seus respectivos Valores do arquivo de messages (lançando a String a propria chave (passada no Parâmetro))! :oops: Será q estou fazendo algo errado??!

Lucas_Cavalcanti

vc não está fazendo nada de errado… é o vraptor que não internacionaliza os parâmetros da mensagem mesmo… =S

posso marcar como bug e corrigir isso… mas por enquanto o jeito mais fácil de fazer isso é colocando o texto não internacionalizado mesmo…

outra coisa: vc não precisa colocar a categoria do erro no jsp se vc não quiser

L

Olá Lucas,

Estou começando a estudar o Vraptor e estou tendo um problema similar ao do Derlon.

Estou também tendo este erro:

"

br.com.caelum.vraptor.view.ResultException: javax.servlet.ServletException: javax/el/ValueExpression

br.com.caelum.vraptor.view.DefaultPageResult.forward(DefaultPageResult.java:69)

br.com.caelum.vraptor.extra.ForwardToDefaultViewInterceptor.intercept(ForwardToDefaultViewInterceptor.java:59)

br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)



Tenti realizar as modificações sugeridas por voces no forum.

EU substitui o jstl-api-1.2.jar e jstl-impl-1.2.jar pelos jstl.jar e standard.jar, Com isso, a exceção assim deixou de acontecer, entretanto, em vez de aparecer os valores do meu objeto produto apareceu a seguinte linha no meu navegador:


  • ${produto.nome} - ${produto.descricao}
    "

Voces saberia me ajudar a esclarecer este meu problema ?

Minha segunda duvida é com relação ao stack trace. atualmente os error que ocorrem apenas estão aparecendo no navegador e não no console do meu eclipse, saberia dizer o q preciso modificar para fazer todos os error aparecerem no console do eclipse ?

Muito obrigado pela atenção, abaixo estarei colocando meu codigo jsp e meu Controler.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@page import="java.util.Map"%>
<%@page import="javax.servlet.jsp.jstl.core.*"%>
<%@page import="java.util.Set"%><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<ul>
<c:forEach items="${produtoList}" var="produto">
    <li> ${produto.nome} - ${produto.descricao} </li>
</c:forEach>
</ul>
</body>
</html>
package br.com.caelum.vraptor.blank.controller;

import java.util.ArrayList;
import java.util.List;

import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.blank.entity.Produto;

@Resource
public class ProdutosController {
	
	private Result result;
	public ProdutosController(Result result){
		this.result = result;
	}
	public List<Produto> list() {
		List<Produto> prodList = new ArrayList<Produto>();
		Produto p = new Produto();
		p.setNome("teste");
		p.setDescricao("teste");
		prodList.add(p);
		result.include("teste", "teste");
		return prodList;
	}

}
Lucas_Cavalcanti

Tenta trocar a primeira linha por:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%>

deveriam estar aparecendo no console tb… vc tá olhando no console do servidor? qual servidor vc tah usando?

L

Olá Lucas, Sua dica resolveu meu problema

Muito obrigado.

Com relação ao servido estou usando o tomcat 5.5, a saída do console mostrou a parto do carregamento do sistema, e outras coisas, entretanto, quando o erro ocorreu ele só apareceu no navegado e não no consolo

obrigado pela ajuda

D

Oi Lucas, (foi mal, o delay :-()

Muito obrigado p/ ajuda, dicas e conselhos!! :thumbup:

Só postei p/ avisar q estou 20 dias de férias, mas logo volto p/ continuar a saga!! 8)
Mas, meus parabens p/ vc, o Silveira, todo o pessoal do vRaptor… A idéia do FrameWork é fenomenal, o vRaptor está cada dia melhor, continuem o ótimo trabalho !! :XD:

A gente se fala,

Derlon

Lucas_Cavalcanti

derlon, agora o vraptor tá internacionalizando os parâmetros das mensagens, mas vc precisa fazer:

//validations
  that(a  > b, "categoria", "mensagem_key", i18n("parametro_internacionalizado"), "parametro não internacionalizado");

baixe o snapshot pra poder fazer isso:
http://oss.sonatype.org/content/repositories/snapshots/br/com/caelum/vraptor/3.1.2-SNAPSHOT/vraptor-3.1.2-20100310.010227-4.jar

D

Oi, Lucas

Substituí o vraptor-3.1.1.jar pelo o (nightly build) q vc me indicou e funfou 100%!! 8) Grato p/ melhoria!!
Apenas 1 observação: para q o Valor da Categoria (de Erro) seja mostrado na .JSP (em vez da Chave), seu parametro tb precisa ser passado c/ a função i18n(“categoria_internacionalizada”), por exemplo, desta forma:

that(!(produto.getDescricao().isEmpty() ), i18n("mandatory.field"), "required_field", i18n("produto_descricao")); Obtendo:
* Preenchimento Obrigatório: Descrição é um Campo Obrigatório.

Agora, estou tentando internacionalizar os Campos assim:

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <fmt:message key="produto_nome"/><br /> , porém tudo q consigo é a Key (chave) entre interrogações (deste jeito):
???produto_nome???

Lucas, saberia dizer qual é o problema??!

Lucas_Cavalcanti

vc precisa registrar o bundle de mensagens no web.xml… tem um exemplo de como fazer isso no mydvds

D

Legal! É usado o esquema padrão de i18n da JSTL! :wink:

Só q agora percebe-se q somente os Nomes dos Campos são internacionalizados. Mas, as mensagens das Validações são exibidas os Valores, porém sem internacionalizar (na verdade isto já estava acontecendo, tanto no EI, como no FireFox).

Ah, outro problema: sempre q faço 1 request p/ 1 Controller da minha Aplicação, no Internet Explorer, apresenta seguinte a msg de Erro (quando tento acessar '[color=darkblue]http://localhost:8080/vRaptor-OnLine-i18n-project/produtos/form[/color]' p/ ex.):
HTTP Status 404 - /vRaptor-OnLine-i18n-project/WEB-INF/jsp/produtos/form.image/gif.jsp

--------------------------------------------------------------------------------

type Status report

message /vRaptor-OnLine-i18n-project/WEB-INF/jsp/produtos/form.image/gif.jsp

description The requested resource (/vRaptor-OnLine-i18n-project/WEB-INF/jsp/produtos/form.image/gif.jsp) is not available.


--------------------------------------------------------------------------------

Apache Tomcat/5.5.28
Aí, eu sempre tenho q Refresh p/ ver a página direito.

O pode estar causando estas issues??!

Lucas_Cavalcanti

isso só acontece no IE? não faz mto sentido…

vc tem uma imagem chamada image.gif na página de form? como vc está referenciando ela?

D

Não, não tem nenhuma imagem no meu projeto (q é apenas o Blank, fornecido p/ site do vRaptor (apenas renomeei o Nome do Projeto p/ ‘vRaptor-OnLine-i18n-project’), adicionados apenas recursos de validação e i18n).

E sim, só acontece no IE. Bem, nunca testei em outros browsers, mas no FF tudo sempre funciona ok!! No entanto, no EI a única pág. q carrega de cara é quando eu starto a Aplicação e ela chama a pág. index.jsp! :shock:

E c /relação à i18n (das MSGs de Validação)??! :frowning:

Lucas_Cavalcanti

a msg é internacionalizada por padrão… já a category e os parâmetros vc tem q internacionalizar na mão com o método i18n

D

Então revisando:
Nos arquivos ‘[color=darkblue]messages_en_US.properties[/color]’ e ‘[color=darkblue]messages_en.properties[/color]’ tenho

Form Produtos

produto_nome=Name
produto.preco=Price

Na Controller:

that(!(produto.getNome().isEmpty() ), "", "required_field", i18n("produto_nome") );
			that(produto.getPreco() == null || produto.getPreco() &gt; 0, "", "smaller_than", i18n("produto.preco"), "0");

Na JSP exibe:

  • Nome é um Campo Obrigatório.

  • Preço menor que 0!


  • Name

    <input type=“text” name=“produto.nome” value="" />

    Price<input type=“text” name=“produto.preco” value="-10.0" />

    Percebe então q algumas coisas são internacionalizadas, mas outras, não! :cry:

    Lucas_Cavalcanti

    o problema é que o do VRaptor tá usando o Locale Pt, e o fmt tá usando locale en…

    onde vc tá setando o locale?

    D

    Estou ajustando direto na configuração (‘Opções’ (de Internet) em ‘Idiomas’) do Browser.
    Há 1 forma + [color=green]prática[/color] de fazer isso??!

    Lucas_Cavalcanti

    dá pra vc colocar links na sua página pra mudar a língua… e vc muda no HttpSession.setLocale se eu não me engano…

    D
    Lucas Cavalcanti:
    dá pra vc colocar links na sua página pra mudar a língua... e vc muda no HttpSession.setLocale se eu não me engano...
    Lucas, eu testei colocando links para a mesma URI concatenada a '?lingua=de' e '?lingua=en' (conforme explicado em [url]http://blog.caelum.com.br/?s=mydvds[/url] - item 5) e em 'form.jsp' adicionando:
    <c:if test="${not empty param.lingua}">
    			  <fmt:setLocale value="${param.lingua}" scope="session"/>
    			</c:if>
    
    e (na verdade, eu já estava suspeitando) infelizmente persistiu o mesmo resultado. Então decidi (colocar o código acima como comentário JSP e) implementar "O LogOn de Aluno" q v6 orientam no Artigo da Revista [color=darkblue]MundoJava[/color] Ed.38 na Seção 'Trabalhando com objetos na sessão'. E na 'LoginController' implementei o método:
    public void mudarIdioma(final String lingua) {
    		this.sessaoDoUsuario.mudarLocale(lingua);
    		result.redirectTo(ProdutosController.class).form();
    	}
    
    Só q, em vez de implementar a Classe @SessionScoped 'UsuarioLogado' (ou 'AlunoLogado' q seja), implementei a Classe:
    @Component @SessionScoped
    public class SessaoDoUsuario {
    	private HttpSession session;
    
    	public SessaoDoUsuario(HttpSession session) {
    		this.session = session;
    	}
    	
    	public void mudarLocale(String strLocale) {
              Locale locale = new Locale(strLocale); // language, country, variant
              Config.set(session, Config.FMT_LOCALE, locale);
              Config.set(session, Config.FMT_FALLBACK_LOCALE, locale); // request.getSession()
    	}
    }
    
    para implementar uma abordagem similar a para Java[color=red]Servlet[/color] e novamente só os
    Lucas_Cavalcanti

    o Validations do vraptor não tá levando em conta o locale =/ (e nem tem mto como fazer isso genericamente, pq vc dá um new nele)

    em todo caso, vc pode fazer (fica um pouco feio, massss):

    validator.checking(new Validations(ResourceBundle.getBundle("messages", locale)) {{
        //suas validações
    }});
    
    D

    Mas, como é q eu faço para passar o (parametro) ‘locale’ para a minha ‘ProdutosController’??! :roll:
    (A propósito, como faço p/ recuperar um Atributo(q está na Session) de dentro de 1 método da minha Controller??! :shock: )

    Lucas_Cavalcanti

    vc pode receber um Localization no construtor, que tem um método getLocale()…

    teoricamente ele pega o locale que está na request/session/context, nessa ordem

    Lucas_Cavalcanti

    qto a atributos da session, se vc usou session.setAttribute na mão, vc só consegue recuperar no vraptor via session.getAttribute (recebendo o HttpSession no construtor)

    se vc usou um componente SessionScoped, basta recebê-lo no construtor

    D
    Agora na pág. apresenta:
    exception 
    
    br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
    ...
    
    Tenho certeza quase total q é quando o método getLocale() de localization é chamado. Será qual o problema??!
    Lucas_Cavalcanti

    o que aparece na stacktrace do servidor?

    G

    Lucas Cavalcanti:
    o Validations do vraptor não tá levando em conta o locale =/ (e nem tem mto como fazer isso genericamente, pq vc dá um new nele)

    em todo caso, vc pode fazer (fica um pouco feio, massss):

    validator.checking(new Validations(ResourceBundle.getBundle("messages", locale)) {{ //suas validações }});

    Já temos planos de usar o Bean Validation? Pergunto porque estou mexendo com isso, e posso fazer isso se vocês ainda não fizeram, já que ví ter uma issue para isso.

    Lucas_Cavalcanti

    a gente aceita contribuições com prazer, garcia =)
    não começamos a fazer ainda…

    []'s

    D
    Lucas Cavalcanti:
    isso só acontece no IE? não faz mto sentido...
    Oi, Lucas. Realmente este prob. estava acontecendo especificamente em meu Projeto. :oops: Estão decidi refazer ele do 0 (p/ isso o delay no feedBack): mas, agora rodando no TomCat 6.0 mesmo e agora tudo está funfando Ok em ambos os browsers! :wink:
    Lucas Cavalcanti:
    o que aparece na stacktrace do servidor?
    E o prob. do 'Localization' (perdão, mas) realmente foi 1 lapso meu no código-fonte. :x Então para me redimir, vai 1 dika :idea: aí para o pessoALL sobre:
    Derlon:
    ... implementar "O LogOn de Aluno" q v6 orientam no Artigo da Revista MundoJava Ed.38 ...
    Q tal criar a @SessionScoped SessaoDoUsuario totalmente desatrelada à 'HttpSession', desta forma:
    @Component @SessionScoped  
    public class SessaoDoUsuario {  
    
    	private Usuario usuarioLogado; //  = new Usuario()
    	
    	public void efetuarLoginDo(Usuario usuario) {
    		this.setUsuarioLogado(usuario);
    	}
    	
    	public Usuario getUsuarioLogado() {
    		return usuarioLogado;
    	}
    }
    
    Daí é só mostrar o 'usuarioLogado' na sua página (ou no seu Include) c/ a EL ${sessaoDoUsuario.usuarioLogado.nome} !! 8)
    Lucas_Cavalcanti

    na época que escrevemos o artigo pra MundoJava, esse uso da EL não era possível ainda… na apostila do VRaptor e na documentação a gente usa esse novo jeito já :wink:

    Obrigado =)

    D

    Oi, Lucas (eu dNovo hehehe!)

    Infelizmente o Erro do (gif.jsp) no EI voltou a acontecer. :frowning:
    Mas, eu descobri o q está causando o problema: foi bem na hora q eu substituí o (.JAR) ‘vraptor-3.1.1.jar’ pelo o (nightly build) ‘vraptor-3.1.2-20100310.010227-4.jar’.
    Enquanto eu mantive o .JAR VRaptor original (do Projeto Blank) o IE funfou normal; e dpois da atualização voltou a issue de ter q dar Refresh em todo Submit.
    Poderia tentar reproduzir a falha??!
    Vlws…

    Lucas_Cavalcanti

    não tenho windows instalado na minha máquina… logo não dá pra eu testar no IE… qual versão vc tá usando?
    IE6? IE7? IE8?

    D

    No IE(ca)7. (hihihi!)

    Lucas_Cavalcanti

    implemente essa classe… deve resolver seu problema:

    @Component
    public class FixedAcceptHeaderToFormat implements AcceptHeaderToFormat {
       public String getFormat(String acceptHeader) {
            return "html";
       }
    }
    

    me diga se funcionou =)

    D

    Sim, funcionou sim! Vlws; Bacana! :lol:

    D

    garcia-jj:

    Já temos planos de usar o Bean Validation? …

    Garcia, Lucas C., outros forks do VRaptor e contribuidores,

    Fantástico: 1 grande idéia no vRaptor ser implementada a integração c/ a JCP - JSR 303: Bean Validation!!! :thumbup:
    E q tal de repente adotar 1 @Anotação (bem ao estilo do Stripes) para definir quais métodos vão ser validados e quais não vão. Ou melhor ainda: por padrão/convenção o form em todos os métodos da Controller é sempre validado; e no(s) método(s) q nós não queremos/podemos validar seus dados, poderiamos simplesmente adotar/adicionar 1 Annotation [color=red]@DoNotValidate[/color] :mrgreen:
    O q acham??!

    Lucas_Cavalcanti

    vc diz validar de acordo com as anotações no modelo?

    G

    Lucas Cavalcanti:
    a gente aceita contribuições com prazer, garcia =)
    não começamos a fazer ainda…

    Lucas, essa semana estou meio dividido na implantação de um sistema (feito com vraptor, claro :slight_smile: ), mas no final de semana vou mexer nisso.

    Lucas Cavalcanti:
    não tenho windows instalado na minha máquina… logo não dá pra eu testar no IE… qual versão vc tá usando?
    IE6? IE7? IE8?

    Já gostava de ver teus códigos, documentações e forma de responder para a galera no fórum. Mas agora ganhou nota mil no meu conceito, hehe. Se eu te contar que eu nem sei trocar um papel de parede no windows tu vai rir de mim, haha.

    derlon:
    Fantástico: 1 grande idéia no vRaptor ser implementada a integração c/ a JCP - JSR 303: Bean Validation!!! :thumbup:
    E q tal de repente adotar 1 @Anotação (bem ao estilo do Stripes) para definir quais métodos vão ser validados e quais não vão. Ou melhor ainda: p/ padrão/convenção o form em todos os métodos da Controller é sempre validado; e no(s) método(s) q nós não queremos/podemos validar seus dados, poderiamos simplesmente adotar/adicionar 1 Annotation [color=red]@DoNotValide[/color] 8)
    O q acham??!

    No início de tudo eu pensei em aproveitar um código inicial que desenvolvi para um projeto aqui na empresa usando vraptor, que é a mesma coisa que o validator que o vraptor tem para o Hibernate Validator, porém usando os validadores da JSR 303. Nesse caso não sei nem se precisa dessa @DoNotValidate, pois você precisa chamar o validator manualmente. Conforme a documentação do vraptor.caelum.com.br:

    public adiciona(Funcionario funcionario) { //Validação do Funcionario com Hibernate Validator validator.addAll(Hibernate.validate(funcionario)); }

    Penso em fazer algo semelhante, por exemplo, BeanValidator.validate().

    D

    Lucas Cavalcanti:
    vc diz validar de acordo com as anotações no modelo?
    Isso mesmo (Validações diretamente (nos Atributos) na Classe Entidade de negócio), Lucas! :wink:

    garcia-jj:
    Penso em fazer algo semelhante, por exemplo, BeanValidator.validate()
    Garcia, o ‘Hibernate Validator’ faz parte (da implementação) do Hibernate, certo??! Então, desta forma, teríamos q dar 1 import do Hibernate na nossa (camada) WebFrontController, q fica, geralmente, a (pelo menos) 2 camadas da layer de Persistência (ou Acesso/Repositório a/de Dados).

    :idea: Assim, IMHO, creio q o “estado da arte” seria podermos colocar 1 Annotation AddValidadion ou ApplyValidadion (sei lá! [color=red]@ApplyValidation[/color]) em nossa Classe Controller e @DoNotValidate no(s) método(s) q nós não precisamos validar!! :twisted:
    E o Stripes consegue, de alguma forma, propagar as Validações do Bean Validation / Hibernate Validator até a View, daí parece q c/ 1 plugIn/frameWork [color=red]AJAX[/color] conseguimos gerar Validações Client-Side! :XD: O q acham?!!
    Obs.: 1. melhor ainda q o Struts2 q, p/ fazer isto, ainda faz isto via .XML (arght)!
    2. Garcia, ainda considero válida sua abordagem/contribuição, até para o amadurecimento (do desenvolvimento) da Validação! :thumbup:

    Lucas_Cavalcanti

    bom… dá pra fazer algo assim, mas é meio ruim ficar poluindo o controller com um monte de anotações… principalmente anotações de comportamento…

    as anotações deveriam ser apenas pra marcação, apenas metadados, e não deveriam habilitar/desabilitar comportamentos

    de qqer forma, prefiro que isso seja programático, algo do tipo:

    validator.validate(objeto);
    

    e vc define o comportamento de validação sobrescrevendo um componente do vraptor… daí vc pode usar como implementação o Hibernate, a JSR-313, o MeuSuperFrameworkDeValidaçãoQueEuFizSozinho, etc…

    D

    (Sem querer ir + off-topic: como está tensa a questão da lincença do JCK para o Apache Harmony: :arrow: http://khanderaotech.blogspot.com/2007/04/jsr-313-for-j2ee-60-received-setback.html c/ atenção especial a ‘Carta Aberta à Sun’ e 'comentários s/ os termos de licença(na JCP). :hunf: )

    Mas, Lucas, vc acha q anotações de comportamento na Controller podem causar efeitos colaterais na integração com WebServices, principalmente na abordagem RESTfull??!

    Lucas_Cavalcanti

    efeitos colaterais acho que não… só prefiro a maneira programática mesmo… nesse caso faz mais sentido um validator.validate(obj); do que um @ApplyValidation no parâmetro ou no método…

    G

    Não, Bean Validator foi impulsionado pelo pessoal do Hibernate, porém ele não faz parte da implementação de Hibernate. Mesmo que fosse o vraptor com seu HibernateValidator já faz uso direto das classes do Hibernate. Embora eu não concorde com isso, o vraptor possui muita coisa que faz uso direto do Hibernate, inclusive o HibernateValidator.validate.

    Concordo contigo. Embora como já citei acima, mesmo não gostando de misturar Hibernate com camada web, não vejo forma melhor de fazer um validador para a JSR303 diferente da forma atual. Conforme você mesmo já disse, é muito mais simples e claro fazer uma espécie de BeanValidator.validate(meuBean). Dessa forma seguimos o padrão que já existe e também mantem-se a simplicidade.

    Anotações parecem legal, mas quando menos anotações melhor. O ideal é você sempre usar anotações como item opcional, não como “item de série”. Lembro de certa vez lendo os docs do Struts 2 a quantidade de anotações necessárias para validar uma simples entrada de dados em uma action: http://struts.apache.org/2.1.6/struts2-core/apidocs/com/opensymphony/xwork2/validator/annotations/Validation.html

    Lucas_Cavalcanti

    nada que o VRaptor usa do hibernate é obrigatório… toda dependência com o Hibernate é opcional dentro do vraptor…

    D

    Garcia, neste ponto o Lucas (como eu diria) is quite sure!:!: Nada no VRaptor nos obriga a usar qq coisa do Hibernate (a pesar q ele tornar a Validação muito menos [color=red]verborrágica[/color]). :hunf:

    G

    Mas em momento algum eu disse que são obrigatórios :).

    E sobre o Bean Validator, o que vocês acham? Abraços

    Lucas_Cavalcanti

    acho que seria legal a gente suportar sim… mas não com um método estático como está agora com o hibernate :wink:

    G
    Lucas Cavalcanti:
    acho que seria legal a gente suportar sim... mas não com um método estático como está agora com o hibernate ;)

    Hmm, comecei a dar uma analisada ontem nisso. Como você acha que deve ser? Um objeto não estático porém injetado assim como o validator?

    public class JSR303Validator { // não repare no nome  :twisted: 
       [blah blah blah]
    }
    
    Usando o bicho.
    public class MyController {
        public MyController(JSR303Validator validator) {
            this.validator = validator;
        }
    
        public void foo(MeuBean bean) {
             validator.validate(bean);
        }
    }
    
    Lucas_Cavalcanti

    acho que pode ser assim:

    -adicionar o método validate(Object) na interface Validator
    -criar uma interface chamada BeanValidator ou coisa do tipo com duas implementações: a do Hibernate e a da JSR303
    -na implementação do Validator, receber um BeanValidator no construtor e delegar a validação pra ele

    que acha?

    D

    garcia-jj:

    Não, Bean Validator … não faz parte da implementação de Hibernate.

    Garcia, me confundi 1 pouco e acabei digitando ‘BeanValidation’ em vez de ‘Hibernate Validator’ (mas, já voltei lá e fiz o ajuste). :expressionless:
    Aproveitando o ensejo: como ficariam, na abordagem q vc está propondo, as validações, digo direto nos atributos e como seria as MSGs de erro, inclusive usando as chaves do Bundle? (P/ gentileza, poderia mostrar 1 ex.?):?: (espero NÃO estar parecendo 1 pessoa “Obcecada” p/ i18n. :roll: )

    Concordo contigo. Embora como já citei acima, mesmo não gostando de misturar Hibernate com camada web, … Dessa forma seguimos o padrão que já existe e também mantem-se a simplicidade.
    Lucas, (“validator.validate(obj)”): vc se refere a Classe ‘Validator’ do VRaptor; e o método ‘validate()’ subentende o disparo de Validações da/e (qq) JSR303 adotada (na nossa Classe-Entidade (devidamente anotada)); em alternativa ao método ‘checking()’ atual abordagem de Validação Fluent (até p/ manter a compatibilidade (c/ versões anteriores))??!

    garcia-jj:

    Anotações parecem legal, mas quando menos anotações melhor. O ideal é você sempre usar anotações como item opcional, não como “item de série”. Lembro de certa vez lendo os docs do Struts 2 a quantidade de anotações necessárias para validar uma simples entrada de dados em uma action: http://struts.apache.org/2.1.6/struts2-core/apidocs/com/opensymphony/xwork2/validator/annotations/Validation.html
    … no Princípio, a Sun criou a obra: J2EE Core-Patterns (Obs.: onde estiver escrito “J2EE Core-Patterns”, leia-se 'EJB Core-Patterns '. :?).
    Um tempo depois, a GoF lançou seu 24 Design-Patterns dividos em 3 categorias.
    Martin Fowler propôs padrões para IoC-InversionOfControl.
    Se continuarmos esta discussão sobre Validação, vamos acabar criando Design-Pattern(s) para Validações! :shock:
    Lucas, desculpe a brincadeirinha, mas esta discussão foi muito importante p/ mim, pois acabei pesquisando e descobrindo a verdadeira essência do conceito de CoC, muito além do significado de suas palavras-chave: Convention - Convenção/Padrão; Over (priorizada em relação); e Configuration. Este conceito reside na “Programmatic Configuration”.
    Garcia, (Karaka!!! :shock: ) no Livro Mentawai in Action :arrow: http://book.mentaframework.org/posts/list/5.page, saoj (não sei se ele é 1 dos criadores do Menta) tb transcreve o [color=red]MEGA VERBORRÁGICO[/color] free-block anotado c/ @Validations (na class SimpleAnnotationAction) citado p/ ti.
    Lucas, os criadores do Mentawai se guiaram em 2 principios para concebê-lo: KISS/Simplicidade (q tb é das abordágens ágeis) e ‘se CoC é bom, leve CoC ao eXtremo’ (só q tão extremo/[color=red]radical[/color] ao ponto de não usar Java[color=red]Annotations[/color] :x) Creio q na atual conjuntura seria impossível imaginar IoC s/ Annotations. Fico muito contente de o VRaptor manter a elegância da simplicidade, porém (usando Annotations na medida certa 8) ) sem deixar de usar os poderosos recursos da IoC!!! :thumbup:

    D

    Lucas Cavalcanti:
    acho que pode ser assim:

    -adicionar o método validate(Object) na interface Validator
    -criar uma interface chamada BeanValidator ou coisa do tipo com duas implementações: a do Hibernate e a da JSR303
    -na implementação do Validator, receber um BeanValidator no construtor e delegar a validação pra ele

    que acha?


    (Mesmo para mim, q não sou nenhum 1 pouco fã de codificar Validações na Action/FrontController) Agora sim! :thumbup: Esta é 1 abordágem bem razoável!! :lol: :wink:

    G

    Lucas Cavalcanti:
    acho que pode ser assim:

    -adicionar o método validate(Object) na interface Validator
    -criar uma interface chamada BeanValidator ou coisa do tipo com duas implementações: a do Hibernate e a da JSR303
    -na implementação do Validator, receber um BeanValidator no construtor e delegar a validação pra ele

    que acha?

    Perfeito. Porém fiquei com dúvida sobre como o vraptor saberá qual implementação dele deve usar, se Bean Validator ou Hibernate Validator 3.X. No meu caso eu usaria o BeanValidator, mas pode ter alguém que queira usar o Hibernate Validator.

    G

    Como o vraptor irá apenas delegar a validação para o BeanValidator, isso dependerá tudo dele. Só que se não me engano quando você inicializa o bean-validator precisa indicar o locale a ser usado. Não sei como o vraptor sabe qual o locale usar internamente, mas podemos fazer uso o atributo javax.servlet.jsp.jstl.fmt.locale para passar o locale para o bean-validator, Lucas?

    Vou ver se faço algo até o final de semana, uma espécie de initial release, e aí podemos ir planejando umas melhoras. Eu ainda não senti a necessidade das annotations, mas acho que tendo essa implementação inicial pode exclarecer um pouco esse ponto para nós.

    Abraços

    D

    D+, Garcia!!! :thumbup:

    Já estou ansioso para ver o resultado (ainda q seja inicial) desse trabalho!! :XD:

    Lucas_Cavalcanti

    garcia-jj:

    Como o vraptor irá apenas delegar a validação para o BeanValidator, isso dependerá tudo dele. Só que se não me engano quando você inicializa o bean-validator precisa indicar o locale a ser usado. Não sei como o vraptor sabe qual o locale usar internamente, mas podemos fazer uso o atributo javax.servlet.jsp.jstl.fmt.locale para passar o locale para o bean-validator, Lucas?

    o vraptor já tem um componente que lê (ou deveria ler :P) esse parâmetro… ele se chama Localization, e vc pode usar no seu BeanValidator

    D
    PessoALL, Tem algum jeito no VRaptor3 de Injetar Dependencias (ou Recursos) do FrameWork e/ou de Objetos de minha Aplicação via [color=red]@In[/color] (como no VRaptor2), +/- assim:
    @Resource
    public class ProdutosController {
    	@In
    	private final Result result;
    	@In
    	private Validator validator;
    	@In
    	private ProdutoSrvcFcd produtoSrvcFcd;
    
    	public void incluir(Produto produto) {
    		produtoSrvcFcd.incluir(produto);
    	}
    	...
    }
    
    :?:
    Lucas_Cavalcanti

    usa o @Autowired do Spring… mas é feio :wink:

    G

    Ficou uma dúvida pendente: http://guj.com.br/posts/list/45/198913.java#1034139

    Lucas_Cavalcanti

    ops :blush:

    daria pra fazer uma condicional: se tiver o jar do Hibernate, registra o do Hibernate, se tiver o do JSR303, registra o do 303, se tiver os dois, registra um wrapper pros dois =)

    G

    Lucas Cavalcanti:
    ops :blush:

    daria pra fazer uma condicional: se tiver o jar do Hibernate, registra o do Hibernate, se tiver o do JSR303, registra o do 303, se tiver os dois, registra um wrapper pros dois =)

    Certo. Agora mais do que nunca vou precisar rever aquele artigo que tu me passou de atualizar meu fork com as últimas alterações do git do vraptor/master :smiley:

    Ps: bagunçamos o tópico das dúvidas pontuais.

    Lucas_Cavalcanti

    nada como uma boa divagação de vez em qdo :wink:

    qqer dúvida sobre git, só dar um toque

    G

    Fiquei com uma dúvida…

    Quando usamos o Bean Validator, o resultado dos erros vem em um iterator de ConstraintViolations, objeto esse que contém uma série de informações sobre a validação, e não apenas a mensagem de validação.

    Para o resultado creio que deveremos usar o ValidationMessages do Vraptor, correto? Sendo assim o resultado das mensagens de erros devem ser interpoladas via MessageInterpolator.interpolate ou extender o ValidationMessages do Vraptor e devolver um objeto com as informações de validação?

    (edit)

    Notei que o bean validator, quando dá um erro de validação, mostra apenas as mensagens cruas do tipo “não é um e-mail válido”. Estou em dúvida de como reportar isso para a tela, se como String ou então (penso ser o melhor) devolver um objeto para que o peão possa tratar na tela. Creio que algo extendendo ValidationMessage do vraptor com os dados das constraint violations.

    D

    Lucas Cavalcanti:
    usa o @Autowired do Spring
    Lucas, Muito Obrigado!! :thumbup: Funfou mesmo!!

    Lucas Cavalcanti:
    … mas é feio :wink:
    Concordo contigo, mas só com relação a Injeção de Dependências (Objetos de Layers da minha Aplicação), pois a configuração fica dúbia (seu eu remover @Component, pára de funcionar): duplicidade de Annotations.:thumbdown: Mas, acerca de Injeção de Recurso, seja de APIs do Java (Servlet/HTTP) ou de FrameWork, fica muito + prático c/ a @Autowired (facilita o Refactoring), pois se o desenvolvedor entender q ele não precisa + do Objeto de 1 API, nada q 1 delete (ou Comment-Out dos) Objetos e Optimize Imports não resolva (c/ alguns clicks). 8)

    Agora tenho 1 Duvidinha - vou ilustrar o ex.: tendo 1 form.JSP (ou produtos/manter) com Dados do Produto carregados no Fomulário. Tendo 1 Botão ‘Alterar’, como faço para q ele chame o método alterar(); e 1 Botão ‘Excluir’, como fazer ele chamar o método excluir()??! Detalhe: [color=red]não[/color] vale usar [color=darkblue]JavaScript[/color]!

    P.S.

    garcia-jj:
    Ps: bagunçamos o tópico das dúvidas pontuais.
    Absolutamente, Garcia! :-o Qq contribuição é sempre bem-vinda!! :thumbup:

    Lucas_Cavalcanti

    garcia-jj:
    Fiquei com uma dúvida…

    Quando usamos o Bean Validator, o resultado dos erros vem em um iterator de ConstraintViolations, objeto esse que contém uma série de informações sobre a validação, e não apenas a mensagem de validação.

    Para o resultado creio que deveremos usar o ValidationMessages do Vraptor, correto? Sendo assim o resultado das mensagens de erros devem ser interpoladas via MessageInterpolator.interpolate ou extender o ValidationMessages do Vraptor e devolver um objeto com as informações de validação?

    (edit)

    Notei que o bean validator, quando dá um erro de validação, mostra apenas as mensagens cruas do tipo “não é um e-mail válido”. Estou em dúvida de como reportar isso para a tela, se como String ou então (penso ser o melhor) devolver um objeto para que o peão possa tratar na tela. Creio que algo extendendo ValidationMessage do vraptor com os dados das constraint violations.

    o Hibernate Validator 3 (que o vraptor já suporta) dá um monte de constraintViolations, que têm o campo q deu o erro e a mensagem… daí é só converter pra uma List do VRaptor…
    não sei como funciona o Bean Validator/Hibernate Validator 4, mas acho que ele tb tem algo do tipo

    Lucas_Cavalcanti

    derlon:
    Concordo contigo, mas só com relação a Injeção de Dependências (Objetos de Layers da minha Aplicação), pois a configuração fica dúbia (seu eu remover @Component, pára de funcionar): duplicidade de Annotations.:thumbdown: Mas, acerca de Injeção de Recurso, seja de APIs do Java (Servlet/HTTP) ou de FrameWork, fica muito + prático c/ a @Autowired (facilita o Refactoring), pois se o desenvolvedor entender q ele não precisa + do Objeto de 1 API, nada q 1 delete (ou Comment-Out dos) Objetos e Optimize Imports não resolva (c/ alguns clicks). 8)

    Vc tb consegue fazer isso com injeção no construtor :wink:

    derlon:

    Agora tenho 1 Duvidinha - vou ilustrar o ex.: tendo 1 form.JSP (ou produtos/manter) com Dados do Produto carregados no Fomulário. Tendo 1 Botão ‘Alterar’, como faço para q ele chame o método alterar(); e 1 Botão ‘Excluir’, como fazer ele chamar o método excluir()??! Detalhe: [color=red]não[/color] vale usar [color=darkblue]JavaScript[/color]!

    vc pode usar com name=_method e value=(PUT|DELETE|POST)… mas não funciona no IE =(

    D

    PessoALL,

    JogoRápido: [color=red]não[/color] podemos fazer OverLoad nos métodos de nossa Controller??! :hunf:

    Lucas_Cavalcanti

    só se usar junto com @Path

    Lucas_Cavalcanti

    na verdade trocando o método http tb funciona (@Get @Post @Put @Delete) só não pode overload sem configuração nenhuma

    D

    Na Controller qual é o método default??!

    G

    Se você não colocar nada em seu método o padrão é ele usar @Get. Caso o Path não esteja declarado será usado nome-do-controller + nome-do-metodo.

    D

    (já dei 1 googlada, mas não achei nada)
    Codifiquei assim: @Post public void manter() { } @Get public Produto manter(final Produto produto) { return produto; } mas, recebi:
    Your logic method must accept HTTP GET method if you want to redirect

    Assim não pode?! :?:

    G

    Bean validator done. Só não consegui publicar porque hoje o github resolveu a me complicar. Nem mesmo consigo publicar um gist.

    G

    derlon:
    (já dei 1 googlada, mas não achei nada)
    Codifiquei assim: @Post public void manter() { } @Get public Produto manter(final Produto produto) { return produto; } mas, recebi:
    Your logic method must accept HTTP GET method if you want to redirect

    Assim não pode?! :?:

    Acho que você inverteu as coisas… @Post deve ser no método que você quer fazer o manter, já que ele que recebera o submit. http://vraptor.caelum.com.br/documentacao/resources-rest/

    Lucas_Cavalcanti

    se vc não especificar o método http via anotação ele aceita todos os métodos…

    pra fazer redirects o método precisa ser @Get, pq a requisição volta pro browser do cliente e o browser manda uma requisição GET pra url de redirect

    use os métodos HTTP do jeito certo (GET pra buscar/visualizar dados, POST pra adicionar, PUT pra adicionar/modificar e DELETE pra remover)

    Lucas_Cavalcanti

    o github tah em manutenção hoje mesmo… =/

    D

    garcia-jj:
    Bean validator done. Só não consegui publicar porque hoje o github resolveu a me complicar. Nem mesmo consigo publicar um gist.
    Q tal postar 1 exemplo agora?!! :wink:

    G
    derlon:
    garcia-jj:
    Bean validator done. Só não consegui publicar porque hoje o github resolveu a me complicar. Nem mesmo consigo publicar um gist.
    Q tal postar 1 exemplo agora?!! :wink:

    Exemplo de uso? Será basicamente a mesma coisa que você já faz atualmente, porém é disponibilizado um método a mais na interface Validator.validate().

    @Resource
    public class JSR303TestController {
    
        private final Result result;
        private final Validator validator;
    
        public JSR303TestController(Result result, Validator validator) {
            this.result = result;
            this.validator = validator;
        }
    
        @Get
        @Path("/303test")
        public void edit() {
            result.forwardTo("/WEB-INF/jspx/jsr303.jspx");
        }
    
        @Post
        @Path("/303test")
        public void store(MyBean myBean) {
            validator.validate(myBean);
            validator.onErrorUse(Results.logic()).forwardTo(getClass()).edit();
    
            result.forwardTo("/WEB-INF/jspx/jsr303.jspx");
        }
    }
    

    Eu não fiz os testes ainda, não sei mexer com esses mocks :twisted:

    D

    garcia-jj:
    @Resource ... public void store(MyBean myBean) { validator.validate(myBean); ...
    Eu não fiz os testes ainda, não sei mexer com esses mocks :twisted:

    É! Na verdade, é 1 falha minha não pesquisar isso. :oops: (Mas, é pq eu tô fazendo 1 intensivãozinho XP! :P)
    Mas, o q eu gostaria de ver são as Validações na sua ‘MyBean’, as Annotations , coisa e tal …

    G

    Isso é coisa do Bean Validation e não do Vraptor. O Vraptor faz apenas um delegate para o Bean Validator. Você pode entender mais sobre ele aqui:

    http://jcp.org/en/jsr/detail?id=303
    http://people.redhat.com/~ebernard/validation/ (esse é o melhor)

    Aqui como anotar os beans:
    http://people.redhat.com/~ebernard/validation/#d0e5601

    D

    O “” pode/[color=red]deve[/color] ser ‘<input type=“submit”’??! O form tb funciona assim?:?: :arrow: Olha:

    <form action="<c:url value="/produtos/adiciona"/>" ><!-- method="post" --> Descrição<br /> <input type="text" name="produto.descricao" value="${produto.descricao}" /><br /> <input type="submit" value="Salvar" /><input type="button" name="_method" value="PUT"> <input type="submit" name="_method" value="DELETE"> </form>

    Lucas_Cavalcanti

    não… é :wink:

    <button type="submit" name="_method" value="PUT">Alterar</button>
    

    e vc precisa colocar o method=“POST” no form

    D

    Lucas Cavalcanti:
    use os métodos HTTP do jeito certo (GET pra buscar/visualizar dados, POST pra adicionar, PUT pra adicionar/modificar e DELETE pra remover)
    Calma, gente! Calma! :expressionless: É apenas 1 projeto básico estendido do Blank (download) e do Tut. VRaptor3! -> É claro q ele não equivale 1 App Web do mundo real! Então (como v6 viram) tive q adicionar (ao Blank) 1 Tela de LogOn (inicialmente contra a minha vontade, mas acabou sendo bom|agregou muito valor) e o seu Form dava 1 Submit [color=red]direto[/color] p/ o Form do ‘Produtos’. Então p/ facilitar tive q colocar 1 tipo de HomePage(menu principal) entre os 2 p/ tentar implementar o OverLoad do manter(); (Obs.: Garcia, eu fiz 1 refactoring de form.JSP p/ marter.JSP).
    Mesmo assim, o código ainda então: @Post public void manter() { } @Get public Produto manter(final Produto produto) { return produto; } @Path("/produtos/{produto.id}") @Get//manter/ @Post public Produto manter(Long id) { return produtoSrvcFcd.recuperarPor(id); } mas, (não me lembro pq) não deu certo. Assim, em vez de usar o ‘manter(Long id)’ (-> Commented-Out), tive q usar o método ‘editar(Long id)’ (para o qual já tinha clonado editar.JSP de marter.JSP) para atender (execurar) a solicitação feita p/ Request e usar o ‘manter(Produto)’ só para fazer o Redirect adequado. (Ah, só ficou faltando adaptar o ‘editar(id)’ p/ abordagem RESTfarian8) ) Aí tudo funfou direitinho!! :smiley:
    Mas, vlws p/ ref.!! :slight_smile:

    D

    Lucas Cavalcanti:
    não… é ;)
    (Ah, a tag ?! :roll: p/ ser sincero, nunca tinha usado.)
    Oi, Lucas! Tô de volta…
    Estive pesquisando s/ MSGs, <display tag; dei 1 googlada, mas nada q esgotasse os assuntos :/)
    Achei muitos posts (c/ discussões) sobre Mensagens de Erro (Exceptions): porém, vc poderia me indicar Ref.s p/ abordagem só q das MSGs de [color=darkblue]Sucesso[/color] :?: ?!
    E como vc sugere “jogar” a nossa Collection p/ a [color=red]Session[/color] p/ q a [color=red]paginação[/color] da <display tag funcione adequadamente, ou qual abordágem de Paginação vc sugere?! :-o

    G

    Depende muito do que você quer com tratamento de erros. Sugiro que você abra um reply no respectivo tópico para não misturar as coisas. Esse post tá bem “hibrido”, hehe.

    Lucas_Cavalcanti

    qta pergunta ao mesmo tempo :wink:

    <blockquote><div class="quote-author">derlon:</div><blockquote><div class="quote-author">Lucas Cavalcanti:</div>não…  é  ;)</blockquote>(Ah, a tag ?! :roll:  p/ ser sincero, nunca tinha usado.)
    
    Oi, Lucas!  de volta…
    
    Estive pesquisando s/ MSGs, <display tag; dei 1 googlada, mas nada q esgotasse os assuntos :/)
    
    Achei muitos posts (c/ discussões) sobre Mensagens de Erro (Exceptions): porém, vc poderia me indicar Ref.s p/ abordagem  q das MSGs de [color=darkblue]Sucesso[/color] :?: ?!
    
    </blockquote>
    
    use uma convenção:
    
    result.include("message", "...."); // nas lógicas
    

    e sempre imprima essa mensagem na sua página, qdo ela existir, em uma cor diferente…
    o mydvds faz isso

    derlon:

    E como vc sugere “jogar” a nossa Collection p/ a [color=red]Session[/color] p/ q a [color=red]paginação[/color] da <display tag funcione adequadamente, ou qual abordágem de Paginação vc sugere?! :-o

    ou vc ignora os parâmetros do display-tag e poe ele pra sempre bater na lógica de listagem (e sempre vai listar tudo), ou usa esses parâmetros pra fazer a paginação de verdade no banco

    D

    Vlws mesmo p/s dicas e sugestões!! :wink:
    Mas… como vc sugere criar 1 Diretório/Pacote no Eclipse p/ implementarmos os Testes Unitários (digo: algo parecido como no netBeans)??! :roll:

    G

    Normalmente eu crio um pacote /src com os fontes Java da aplicação e um /test com os testes para rodar via JUnit.

    D
    Escuta, e qual é o problema de (se eu não usar [color=red]Mockery[/color]) eu instanciar a minha dependencia c/ new ClassOfLayer() assim:
    public class LogonControllerTestCase {
        @Test(expected=ValidationException.class)
        public void testValidacaoDeUsuarioInvalido()   
        {   
           /* Mockery mockery = new Mockery() {{   
                  setImposteriser(ClassImposteriser.INSTANCE);   
                }};   
            ProdutoSrvcFcd dao = mockery.mock(ProdutoSrvcFcd.class);   */
        	SessaoDoUsuario dao = new SessaoDoUsuario();   
            MockResult result = new MockResult();   
               
            LogonController controller = new LogonController(dao, result, new MockValidator() );   
            ...;   
        //    Assert.assertNull(result.included("msgFalha")); // estados  
        }   
    }
    
    :?:

    Ah, Lucas,
    O código da 'Listagem 16' do artigo da MundoJava não explicita como a Instancia de alunoDao é(deveria ser) criada! :(

    Lucas_Cavalcanti

    o problema de você não usar mocks é que vc não vai estar escrevendo testes unitários… se você está usando a implementação real de tudo, seus testes são funcionais, e vc não consegue testar comportamentos específicos da sua classe em teste…

    acho que o artigo não explicita a criação das instâncias pq vc nunca vai criar instancias dos seus componentes na mão… vc sempre recebe no construtor e o vraptor se vira pra fazer isso…

    D

    Lucas,

    (Num vô nem entrar no mérito da questão de Estilo de Teste: Classicista, ou Mockista, ou Behavorista(Comportalista)! (até p/ não ir OffTopic) :shock: )

    Mas, então existe algum Mock para o Localization (p/ o caso de [color=red]Validação Internacionalizada[/color])??!

    Lucas_Cavalcanti

    existe: mockery.mock(Localization.class) :wink:

    é uma interface, vc pode mocká-la do jeito que vc quiser…

    a gente só criou um MockResult e um MockValidator pq eles tem interfaces fluentes, e isso torna dificil mockar com os frameworks de mock existentes…

    D

    Bacana, Lucas!
    Excelente v6 terem adicionado ‘MockResult’ e ‘MockValidator’ ao FrameWork :thumbup: …facilita muito a vida, mesmo p/ desenvolvedores q adotam o estilo clássico!!

    Tenho 1 perguntinha 1/2 boba (mas, tb gostaria de saber os porquês): se, na minha Controller, eu tenho 1 método lista(): public List<Produto> lista() { return produtoSrvcFcd.listaTodos(); //result.include("produtos", ); } , no meu TestCase, eu não posso [color=red]testar assim[/color]: ... List<Produto> produtos = produtosController.lista(); Assert.assertNotNull(result.included("produtoList")); :?:

    Lucas_Cavalcanti

    se o método retorna a lista, vc não precisa verificar o result, vc verifica o retorno mesmo :wink:

    transformar o retorno em um atributo do result é responsabilidade do VRaptor, logo vc não precisa testar isso… (assim como vc não testa se a Session do hibernate está salvando mesmo o objeto no banco)

    D

    Normalmente eu crio um pacote /src com os fontes Java da aplicação e um /test com os testes para rodar via JUnit.
    Mas, desta forma, invariávelmente vou acabar com .JARs da Ferramenta de Test [color=red]misturados[/color] com os .JARs da minha Aplicação (e os .JARs dos FrameWorks adotados)??! :shock::?:

    G

    Não, porque se você gerar um jar pelo netbeans ou eclipse você seleciona quais source-folders vão para o jar. Caso você use o ant você pode também indicar quais pacotes vão. Basta você excluir todos onde o source folder é de teste.

    D

    (Lucas, e) VRaptor forks,

    E realmente não tem jeito de configurar (registrar) via [color=red]somente código-fonte[/color] estes: EntityManagerCreator, EntityManagerFactoryCreator e JPATransactionInterceptor; em vez de no web.xml

    <context-param> <param-name>br.com.caelum.vraptor.provider</param-name> <param-value>br.com.caelum.vraptor.util.jpa.JPACustomProvider</param-value> </context-param> :?:

    G

    derlon:
    (Lucas, e) VRaptor forks,

    E realmente não tem jeito de configurar (registrar) via [color=red]somente código-fonte[/color] estes: EntityManagerCreator, EntityManagerFactoryCreator e JPATransactionInterceptor; em vez de no web.xml

    <context-param> <param-name>br.com.caelum.vraptor.provider</param-name> <param-value>br.com.caelum.vraptor.util.jpa.JPACustomProvider</param-value> </context-param> :?:

    Essa semana eu estava pensando nisso, e até pensei em sugerir um componente que você indicar os componentes que você quer inicializar, sem precisar do web.xml.

    public interface Configurator { List<?> doConfigure(); }

    public class EmptyConfigurator { public List<?> doConfigure() { return Collections.emptyList(); } }

    Então se o desenvolvedor quiser subir o componente MeuComponente e o EntityManagerFactory teria algo como

    public class CustomConfigurator { public List<?> doConfigure() { [...] list.add(MeuComponente .class); list.add(EntityManagerFactory.class); return list; } }

    Eu não sei se não dá para você sobrescrever o BaseComponents… Isso o Lucas que conhece bem.

    Lucas_Cavalcanti

    Então, por enquanto o único jeito é criando um CustomProvider que estende SpringProvider e registra esses componentes…
    ou registrando o JPACustomProvider mesmo…

    o problema em criar um componente que registra outros componentes é que eu teria que executá-lo logo após iniciar o Spring, e após iniciar o Spring eu não posso simplesmente registrar novos componentes… Isso até funciona, mas eu precisaria dar um refresh no spring que reinstanciaria todos os componentes…

    pode ser que tenha algo no spring que possibilite isso, mas não conheço…

    rogerio.alcantara

    Olá pessoal que manja do VRaptor3, tudo bom? =D

    Estou analisando qual algumas tecnologias para iniciar um novo projeto e VRaptor3 é um dos candidatos.

    Entretanto, tenho uma dúvida que cheguei a pesquisar nos demais posts mas não achei a resposta…

    Reparei que tanto no tutorial de 3 minutos, quanto no de 10 ou no mydvds, há annotations do vraptor em controllers, Daos e etc. Reparei também nos testes das Controllers (ou seja, há regra de negócio e/ou validações nas controllers) e na utilização das DAOs direto nas Controllers. Finalmente, uma última observação: no modelo, mydvd, não há separação de projetos, (como um projeto só para a regra de negócio, outro para a parte de visualização e etc).

    Minha dúvida é sobre o alta dependência da tecnologia (no caso VRaptor) com a implementação do projeto. Não seria mais interessante se as camadas fossem mais isoladas, para serem mais portáteis?

    Recentemente participei de um projeto onde a regra de negócio (entidades/serviços/repositorios/daos e etc) estava bem isolada em um jar com seus testes de unidade. No meio do projeto, devido a baixa produtividade que a equipe estava tendo no projeto da camada de visualização (JSF+Facelets+RichFaces), foi decidido alterar a tecnologia. Foi criado um novo projeto para camada de visualização utilizando Struts2+Tiles+JQuery, e referenciado o jar com a regra de negócio.

    Como todas as camadas estavam isoladas, toda a regra de negócio estavam nos objetos, serviços, repositorios e etc e eram acessadas por fachadas a mudança foi muito simples, bastando efetuar as chamadas que eram feitas nos ManagedBeans nas Actions.

    Lógico que houveram adaptações, porém o importante é que não foi necessário re-escrever nenhuma regra de negócio e que a transição foi muito rápida.

    A melhor abordagem ao utilizar o VRaptor é realmente manter as regras/validações nas controllers (que, como há testes de unidade, entendo que são encaradas como parte do negócio), e utilizar as DAO’s nas controllers mesmo, e deixar tudo em um mesmo projeto, como o modelo MyDvds?

    Qual seria um possível modelo ao utilizar uma abordagem mais DDD em um projeto VRaptor?

    Por favor me perdoem pela mensagem verborragica, realmente as vezes me acho muito prolixo, porém não encontrei uma maneira mais sucinta de descrever a minha dúvida.

    Se houver algum post que comente esses tópicos, por favor me indiquem.

    Agradeço antecipadamente,

    Lucas_Cavalcanti

    Então, rogério,

    você pode sim ter um projeto pra cada área do seu sistema sem problemas…

    a única coisa é que pra usar a parte de Injeção de Dependências do VRaptor vc precisa usar algumas das suas anotações… se vc não quiser isso, vc pode gerenciar as dependências diretamente num xml do spring, só é mais trabalhoso, mas deixaria seus daos/repositories desacoplados do vraptor…

    de qqer forma, o acoplamento com o vraptor é só via anotações, que vc pode simplesmente apagar depois…

    o VRaptor está com planos de usar anotações padrão do java pra fazer a injeção de dependências, daí eliminaria esse acoplamento tbm…

    as views já são totalmente desacopladas do vraptor, e a parte dos Controllers vc consegue isolar do seu código de negócio…

    G

    Talvez o que eu fale aqui o Lucas já tenha dito, mas a minha opinião é mais de usuário que a dele :D. O Vraptor não é (tão) acoplado a nenhuma classe interna dele porque você não precisa estender nem implementar (quase) nada. As únicas classes que você precisa implementar amarradas diretamente ao vraptor são os converters e interceptors. Porém como esses componentes são de infra não vejo um problema. O fato de ter anotações não significa (forte) acoplamento, pois você pode facilmente remove-las sem muita perda de tempo. Ou seja, acoplamento muito baixo.

    Você disse que usa JSF. Ele sim é bem intrusivo, pois você precisa trabalhar direto com os seus componentes (ex SelectItem). No Vraptor você pode trabalhar totalmente sem sequer saber quem é Vraptor, excetuando o uso do @Resource, que é a única coisa do Vraptor que você não tem como escapar de usar. Todas as outras são bem opcionais. Por exemplo, se você usa EJB não precisará de @Component para daos, repositórios e business.

    O core do Vraptor é ser um controlador, sendo assim você pode usá-lo apenas como controlador unido a N tecnologias, seja suas proprias classes de negócio “made in home”, EJB, Spring ou as camadas do Vraptor. Os projetos de exemplo são meros exemplos, e você pode expandir esses exemplos conforme suas necessidades. Eu por exemplo uso o Vraptor atuamente em 8 projetos com EJB3 remoto, sendo que o Vraptor atua apenas no controlador, e a camada view é feita via JSPX. Eu vejo as daos como meros componentes opcionais do Vraptor, e você pode nem mesmo querer usar eles, como é meu caso.

    Eu sou dos tempos que o Struts estava recém aparecendo no mercado, e nele você tinha dependencias direta do framework porque era necessário não apenas você estender as classes, mas também respeitar uma assinatura de método. No Vraptor você pode escrever seu método como bem entender e ele se vira para injetar os parametros, sejam lá qual for.

    Hoje em dia dizer que você terá um sistema 100% desacoplado me parece um pouco utópico. O que você tem são sistemas que você pode ter poucas dependencias que facilitem a migração para uma nova tecnologia, porém nunca você poderá dizer que vai sair de um framework X para Y sem mexer em nada. Até mesmo no JPA você precisa alterar as propriedades dentro do persistence.xml antes de mudar seu provider. A grande vantagem no Vraptor é que essa dependencia é quase nula.

    D

    rogerio.alcantara:
    … No meio do projeto, devido a baixa produtividade que a equipe estava tendo no projeto da camada de visualização (JSF+Facelets+RichFaces), foi decidido alterar a tecnologia…
    Nesse ponto, a opção + simples e óbvia 8) seria adotar SeamFramework!! (mas, aki isto já iria off-topic :shock: )

    rogerio.alcantara:
    …A melhor abordagem ao utilizar o VRaptor é realmente manter as regras/validações nas controllers (que, como há testes de unidade, entendo que são encaradas como parte do negócio), e utilizar as DAO’s nas controllers mesmo, e deixar tudo em um mesmo projeto, como o modelo MyDvds?
    Rogerio, neste aspecto concordo totalmente contigo!!:thumbup: Sou [color=red]totalmente contra[/color] codificar Validações na Camada (Web)FrontController, pois Lógica, Fluxo e Regras de Negócio devem ficar no Business-Core da Aplicação e, francamente, a maior parte (quando não todas) das Validações são Regras de Negócio.
    rogerio.alcantara:
    … Foi criado um novo projeto para camada de visualização utilizando Struts2+Tiles+JQuery, e referenciado o jar com a regra de negócio.
    omo todas as camadas estavam isoladas, toda a regra de negócio estavam nos objetos, serviços, repositorios e etc e eram acessadas por fachadas a mudança foi muito simples, bastando efetuar as chamadas que eram feitas nos ManagedBeans nas Actions.
    Qual seria um possível modelo ao utilizar uma abordagem mais DDD em um projeto VRaptor?
    Oh Rogério, parece q vc tá lendo o meu pensamento. :wink: É, atualmente estou muito seduzido por essa abodágem de implementar a API do Business-Core em 1 Projeto .JAR(expondo as funcionalidades via interface: Façade de Serviço) e então adicioná-lo ao [b]Projeto .WAR/b
    Mas, com certeza: podemos implementar, sim, :XD: DDD com o v|raptor3!! :thumbup: E isto é até muito facilitado devido a integração [color=blue]transparente[/color] do VRaptor com o Spring. Apenas, devemos mudar algumas abordágens como, por exemplo, a Persistência deve ser Gerenciada pelo Container (no caso, Spring) e tudo + de [color=red]Infra[/color] de forma transversal; enfim: tirar todo o proveito possível da [color=red]AOP[/color] (do Spring).
    Espero ter sido claro! Se faltou alguma coisa, é só postar!! :lol: 1 ]o['ão,

    G

    :thumbup: :thumbup:

    Já que não achei uma emoticon de reverência, usei essa, hehe.

    Atualmente uso assim. Módulo EJB valida tudo, desde campos nullables quanto regra de negócio.

    D

    garcia-jj:

    Não, porque se você gerar um jar pelo netbeans ou eclipse você seleciona quais source-folders vão para o jar. …

    Garcia, E no Eclipse realmente não tem mesmo como fazer esta configuração de Incluir/Excluir SrcPacks/.JARs só q EM Projetos (Web) .WAR??! :cry:

    G

    Derlon, se você ir no projeto, propriedades, Java Build Path, Order and Export você pode marcar quais vão para o export ou não.

    D

    Garcia,
    Sua orientação procede rigorosamente. Porem, tanto o item Pack de Source (código-fonte da minha Ap. propriamente dito), como o de Testes (testes.src) aparecem desabilidos com “um quadradinho” em seus CheckBoxes, ou seja, não consigo checkar e/ou descheckar o CheckBox desses itens. :shock:
    Vc saberia dizer pq acontece isto??! :?:

    Lucas_Cavalcanti

    se vc usar o maven ou o ant pra gerar seus wars vc não vai ter esse problema

    rogerio.alcantara

    Muito obrigado ao @LucasCavalcanti, @garcia-jj e ao @derlon pelos esclarecimentos e aos demais pela atenção.

    Sim, acho que farei um projeto a parte para o core/testes do negócio (JAR) e um projeto web (WAR), pois da última vez ficou muito legal! :stuck_out_tongue:

    Se for o caso de optar pelo VRaptor3, provavelmente precisarei de ajuda na configuração dos projetos e tenho certeza que poderei contar com vcs! :wink:

    Mais uma vez, muito obrigado pela atenção!

    G

    derlon:
    Garcia,
    Sua orientação procede rigorosamente. Porem, tanto o item Pack de Source (código-fonte da minha Ap. propriamente dito), como o de Testes (testes.src) aparecem desabilidos com “um quadradinho” em seus CheckBoxes, ou seja, não consigo checkar e/ou descheckar o CheckBox desses itens. :shock:
    Vc saberia dizer pq acontece isto??! :?:

    Bah, o pior que você tem razão, não dá para desabilitar. Agora que eu olhei isso e é verdade.

    Complementando ao comentário do Lucas, por um lado a IDE mesmo tendo a facilitade de gerar um war, a funcionalidade principal é ser um ambiente de desenvolvimento. Para gerar seu WAR/EAR o ideal mesmo é usar um Ant ou Maven (eu uso o Ant). No meu caso eu trabalho sempre com a IDE para desenvolver, e quando vou empacotar a aplicação para enviar ao cliente o Ant gera um pacote com EAR e até os scripts do banco para migrar as versões, além de ofuscar os códigos, já que 70% das minhas aplicações são vendidas a N clientes.

    Como eu te disse antes, eu separo dentro do Eclipse os source-folders em /src e /test, obviamente src para os fontes do projeto e test para as classes envolvidas no teste. Quando eu quero rodar todos os testes posso usar a IDE ou rodar uma Ant Task que faz isso tudo para mim.

    Além disso a cada commit no repositório do SVN há uma outra task que roda os planos de teste e faz o deploy da aplicação em um ambiente de desenvolvimento central. Há um post no blog da caelum sobre integração continua: http://blog.caelum.com.br/2008/11/04/integracao-continua/

    Criado 22 de fevereiro de 2010
    Ultima resposta 6 de mai. de 2010
    Respostas 114
    Participantes 5