Masterpages usando VRaptor 3

45 respostas
L

Olá pessoal,

Andei procurando mas até agora não consegui achar, é possível trabalhar com masterpages usando o VRaptor 3 ?
Tipo masterpages do ASP.NET, se for possível alguem poderia me dar uma dica de como fazer isso ?

Outra duvida que tenho é se é possível redirecionar para a Action atual, por exemplo, tenho uma controller chamada AssinanteController, nesta tem um método logar()
eu gostaria de deixar um form para login no topo de todas as paginas ai por exemplo estou na página Produtos, vou lá preencho o login e pronto passou no login ele volta para a pagina Produtos e não redir para uma pagina especifica (no caso aqui seria a index)

Obrigado

Att.
Leonardo Lima

45 Respostas

rdgms

Procura os view … standalone da vida!
Tiles 2…Velocity…
A outra pergunta… acredito que com o @Remotable… mas isso era no outro vraptor… ve como esta nesse! (se mudou)
Abraço!

Lucas_Cavalcanti

pra masterpages vc pode usar o Tiles ou o sitemesh…

qto a fazer login e voltar pro mesmo lugar, vc pode fazer o login via ajax (daí nem sai da página que vc tá)
ou redirecionar pro referer… mas o referer não é garantido

result.use(referer()).redirect();
L

Vou ter de estudar um bocado pelo que eu vi…
rsrs bem que poderia ter algo mais simples rsrs
bom mesmo assim muito obrigado!!

Mais tarde quando eu começar a fuçar nessas crianças eu vou ter mais duvidas, ai eu volto :stuck_out_tongue:

Lucas_Cavalcanti

se a sua master pages é só adicionar um cabeçalho e um rodapé em todas as páginas (+ css) é bem simples de fazer, e vc não precisa usar nada além de jsp puro…

só criar dois arquivos (header.jspf e footer.jspf, por exemplo), salvá-los no seu WebContent, e colocar isso no web.xml:

<jsp-config>
		<jsp-property-group>
			<url-pattern>*.jsp</url-pattern>
			<include-prelude>/header.jspf</include-prelude>
			<include-coda>/footer.jspf</include-coda>
		</jsp-property-group>
	</jsp-config>
D

Lucas, esse código que vc postou é o VRaptor que faz o include nas páginas, ou tem outro framework?
Outra pergunta, se for o VRaptor que faz os includes, tem outros tipos de include(include-prelude e include-coda) ou tem outras opções?
Eu estou pra começar uma nova aplicação e estava pensando no tiles, mais já que isso já existe não vai ser necessário o tiles, ja que existe essa forma que vc mostrou.

G

Isso que o Lucas mandou, prelude e coda, é da especificação do JSP 2.0. Ou seja, não é proprietário do Vraptor e funciona para qualquer coisa que use JSP, independente do framework.

D

Hum, legal.
Obrigado.

L

Pessoal,

Estou com um pouco de dificuldade para começar com o VRaptor 3 + Sitemesh, alguem teria um tutorial um pouco mais direto para este assunto?

Obrigado

Att.
Leonardo Lima

G

Seu problema é entender o sitemesh, vraptor, ou integração entre ambos?

L

Boa noite Garcia,

É um pouco de tudo rs, então no atual momento eu estou tentando fazer o Sitemesh funcionar com o VRaptor, peguei o blank-project que tem no site do Sitemesh, copiei a parte de registro do web.xml, criei o decorator, e estou trabalhando só com a main.jsp, coisa bem básica, mas não consegui fazer o VRaptor usar o sitemesh, pior que não deu nenhum erro :confused:

meu web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>webEvto</display-name>
    <!--
		VRaptor will scan classpath for all @Component and
		@Resource inside WEB-INF/classes

		If you want to load them also from WEB-INF/lib/ jars,
		you need to specify from which packages they will
		be loaded, comma separated:
	-->
    <!--
	<context-param>
        	<param-name>br.com.caelum.vraptor.packages</param-name>
	        <param-value>br.com.caelum.vraptor.blank</param-value>
    </context-param>
     -->
    <!--
	   if you are using a servlet 3.0 container
		as glassfish 3 or jetty 8, you dont need this
		filter configuration
	-->
    <filter>
        <filter-name>vraptor</filter-name>
        <filter-class>br.com.caelum.vraptor.VRaptor</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>vraptor</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

decorator.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<decorators defaultdir="/decorators">
    <decorator name="main" page="main.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

Agora criei a pasta decorator direto em WebContent tem de criar dentro do web-inf/jsp ??

Obrigado pela atenção

G

Eu não conheço nada do sitemesh, mas vou tentar te ajudar.

Sitemesh possui algum servlet estilo o tiles? Pergunto porque há algum tempo eu usei tiles em testes com Vraptor, e o que eu fazia era criar um servlet que respondia ao tiles. Então todos os acessos ao tiles ficava algo como:

/customer-list.tiles

Ou seja, o meu servlet do tiles era *.tiles.

Assim todo forward do Vraptor ao invés de ir para um JSP ia para esse servlet do tiles. A idéia você encontra nas receitas de bolo do vraptor e pode te ajudar a pensar em algo para o sitemesh. http://vraptor.caelum.com.br/cookbook/usando-tiles-com-vraptor3/

Assim ambos ficam desacoplados.

L

Então cara…

Eu vi esse cookbook, mas não consegui entender direito não…
Será que eu tenho de implementar um PathResolver também para utilizar o sitemesh ?

Lucas_Cavalcanti

Não precisa de um path resolver não, você só precisa mudar a ordem dos filtros…

esse projeto tem o VRaptor e o sitemesh rodando juntos (com algumas customizações que talvez não sejam necessárias para você)

se você precisar de ajuda para entendê-las é só falar

G

No caso o tiles era usado como servlet, então era necessário um path resolver customizado. Porém no caso do Sitemesh, que o Lucas citou usar filter, não precisa path resolver.

L

Ae pessoal,

Consegui fazer funcionar o Sitemesh!! eba…
Então agora surgiu outra duvida… por exemplo se eu quero ter um link que está no decorator por exemplo (“Fazer algo Importante”) e esse link só pode estar disponível quando o usuario estiver logado (estou usando o esquema de login com do FJ28) para conseguir isso eu tenho de injetar o UsuarioWeb em todas as controllers ou existe algo em comum para simplificar um pouco (se eu jogar uma controllermaster por ex, e fizer minhas controllers herdarem dela será que funfa?)

Outra duvida é que depois de navegar um pouco no sistema, eu notei que minha url está sendo modificada com o seguinte parametro ;jsessionid=EB17180293108E2418BE7B5C9D173092

de onde vem isso ???

Valeu :wink:

Lucas_Cavalcanti

${usuarioWeb} funciona nas jsps

o jsessionid é o identificador das sessões no servidor…

L

Problema...

Socorro!! rsrs

Então eu tava usando o vraptor blank project, ai decidi mudar o nome da IndexController para HomeController,

fui lá mudei o nome da pasta dentro de jsp, refatorei a controller, tudo supostamente certo, mas quando fui rodar....
exception 

java.lang.IllegalStateException: There are two rules that matches the uri '/' with method GET: [[FixedMethodStrategy: /                                                                 HomeController.index()                                                 ALL], [FixedMethodStrategy: /                                                                 IndexController.index()                                                ALL]] with same priority. Consider using @Path priority attribute.
	br.com.caelum.vraptor.http.route.DefaultRouter.checkIfThereIsAnotherRoute(DefaultRouter.java:106)
	br.com.caelum.vraptor.http.route.DefaultRouter.parse(DefaultRouter.java:97)
	br.com.caelum.vraptor.http.DefaultResourceTranslator.translate(DefaultResourceTranslator.java:51)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:64)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
	com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
	org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)


note The full stack trace of the root cause is available in the Apache Tomcat/6.0.26 logs.

o que pode ser!?!?!

Detalhe acabei de ver que isto só acontece quando estou Debugando (PS: Estou usando o Netbeans 6.9)

Lucas_Cavalcanti

provavelmente o .class do IndexController ainda existe…

dar um clean no projeto deve resolver

L

Dammit… achei…

em WebContent\WEB-INF\classes havia as classes, fui lá e apaguei funcionou…
o problema agora é que ele não gerou mais nesta pasta, só gerou na proj\dist…

Bom continuo aqui vlw :stuck_out_tongue:

Mestre…

Deixa eu perguntar de novo…

@Post
    public void login(Assinante assinanteLogin) {
        Assinante assinanteCarregado = assinanteDAO.getAssinanteByEmail(assinanteLogin.getEmailAssinante());
        if (assinanteCarregado != null) {
            String senhaCrypt = CryptUtil.encrypt(assinanteLogin.getSenhaAssinante());
            if (senhaCrypt.equals(assinanteCarregado.getSenhaAssinante())) {
                this.usuarioWeb.login(assinanteCarregado);
                result.redirectTo(HomeController.class).index();
            } else {
                validator.add(new ValidationMessage("Senha informada está incorreta.", "assinante.senhaAssinante"));
            }
        } else {
            validator.add(new ValidationMessage("Usuário não encontrado.", "assinante.emailAssinante"));
        }
        validator.onErrorUse(page()).of(AssinanteController.class).login();
        result.redirectTo(HomeController.class).index();
    }
@Post
    public void login(Assinante assinanteLogin) {
        Assinante assinanteCarregado = assinanteDAO.getAssinanteByEmail(assinanteLogin.getEmailAssinante());
        if (assinanteCarregado != null) {
            String senhaCrypt = CryptUtil.encrypt(assinanteLogin.getSenhaAssinante());
            if (senhaCrypt.equals(assinanteCarregado.getSenhaAssinante())) {
                this.usuarioWeb.login(assinanteCarregado);
                result.redirectTo(HomeController.class).index();
            } else {
                validator.add(new ValidationMessage("Senha informada está incorreta.", "assinante.senhaAssinante"));
            }
        } else {
            validator.add(new ValidationMessage("Usuário não encontrado.", "assinante.emailAssinante"));
        }
        validator.onErrorUse(page()).of(AssinanteController.class).login();
        result.redirectTo(HomeController.class).index();
    }

Eu acho…

Que este erro está sendo causado por que tá rolando 2 result.redirectTo(HomeController.class).index();

Mas a duvida é na hora que eu mando dar o result.redirect, ele não deveria parar a execução e ir embora pra onde eu mandei ???
Vou ter de dar um return; logo abaixo do result se eu quiser que pare ali ?

Bahhh…
Era isso mesmo… dei o return; e funciono…
Caramba podia ter um método de result que já cortava a execução no ponto que o mesmo é chamado né ?! rsrs

L

Boa tarde pessoal,

Nova duvida…
Na hora de carregar meu form de edição minha data está vindo FULL, eu gostaria de formatar ela, então a duvida é, tem que fazer algum @Converter no VRaptor ou basta apenas usar a tag JSTL <fmt:formatDate value=‘valor’ pattern=“dd/MM/yyyy”/> ???

Obrigado

Att.
Leonardo Lima

G

Via JSTL

L

vlw!
deu certo rs
tem hora que eu me esqueco e jogo value="" ai a jstl dentro, e tem mais “” ai quebra linha, rsrs na pressa até ver oq é :stuck_out_tongue:

L

Opa olha eu aqui de novo…

Duvida sobre JSON agora…
Por exemplo, estou fazendo um esquema de login ajax, então eu preciso retornar o seguinte json {“success”:false},“mensagem”:“ERRO”}

E estava lendo sobre como dar o result.use(json()) e fiquei com a seguinte duvida, vou ter de criar um objeto especifico com atributos success e mensagem para que o vraptor serialize, ou vou ter de escrever esse json na mão já que não tenho um objeto ??

Alguem tem um exemplo de um caso que seja parecido ?

Obrigado

Att.
Leonardo Lima

G
Não sei bem se há uma outra forma, mas eu uso sempre objetos de verdade. No caso eu criaria um objeto parecido:
public class Response {
    private boolean success;
    private String message;

    // getters
}
L

é rapaz não tive escolha acabei criando uma classe… agora depois se sobrar tempo quero ver se tem algo parecido com o JObject do C# aquele lá é legal rsrs

L

Garcia tá por ai???

Então, estou com um problema de encoding aqui…
todas minhas páginas estão configuradas para utilizar o UTF-8

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Até agora não tinha tido nenhum problema com encoding, mas agora quando fiz o ajax, o json veio corrompido nos acentos…
Eu tenho de forçar encoding em algum lugar ???

Eu vi um post em que o Lavieri falou para usar a seguinte entrada…

<context-param>    
    <param-name>br.com.caelum.vraptor.encoding</param-name>    
    <param-value>ISO-8859-1</param-value>    
</context-param>

tu já viu isso ??? mas nesse caso eu vou ter de colocar para UTF-8 não ? isso se eu tiver de colocar está config né?

Valeu!

bahh era isso msmo…
joguei UTF-8 no context-param e funcionou… vamos ver se não afetou mais nada :wink:

G

Por aqui eu uso tudo UTF-8, até porque já é herdado do Linux pelo Eclipse, Glassfish, etc.

Há algum problema de você mudar para UTF-8? Faça um teste e mude no Eclipse o encoding do seu projeto para UTF-8, além da configuração que o Lavieri falou, porém para UTF-8.

L

ae rs já tava tudo UT8 mesmo, rsrs só faltou a config do Lavieri, rsrs e só para ser do contra to usando o Netbeans :stuck_out_tongue: rsrs

L

Lucas ou Garcia,

Deixa eu perguntar, quando eu uso um result.redirect eu preciso dar um return, caso exista logica abaixo desse return que não deva ser executada?

if (!usuarioWeb.isLogado()) {
        result.redirectTo(AssinanteController.class).login();
        return;
    }

continua a logica de execução se tiver logado…

Tá certo isso?

Ou basta apenas dar o result.redirect ???

Obrigado

Att.
Leonardo Lima

Lucas_Cavalcanti

o método é sempre executado até o final…

a menos que vc use o validator.onErrorXXX, pq ele para o método qdo existem erros

L

Salve!!

Eu to com um pequeno grande problema, estou usando o SiteMesh, mas como sempre to apanhando da criança, preciso fazer o render de uma página sem a estrutura do decorator (no caso para fazer uma listagem ajax), então eu tava vendo aquela parte do na config dos decoratos, só que eu não estou conseguindo fazer um padrão para isso…
saca eu precisava fazer algo /controller/actionXyList/ID

isso que eu pensei

ai eu travei na hora de montar o pattern, seri /*/List/ ???

Valeu!!!

Lucas_Cavalcanti

é possível que isso funcione sim…

uma boa tática é decorar só os jsps, pq afinal são eles que são decorados de qqer forma…

daí como o json não cai em jsps, não vai ser decorado

L

hummm
mas ai eu teria de usar no link controller/action.jsp não ?

mas acabei fazendo deste modo:

//lista

deu certo, rsrs nem acabei testando aquela pattern doidona, rs fui testar essa primeiro e deu certo ai já viu né ficou :stuck_out_tongue:

Lucas_Cavalcanti

não precisa acessar a jsp direto…

o sitemesh consegue decorar requisições feitas só no servidor (forward)

L

duvida boba…
qual é a diff. de result.forwardTo para result.redirect ???

Lucas_Cavalcanti

o forwardTo faz redirecionamento do lado do servidor, tudo fica na mesma requisição, é possível compartilhar atributos e parâmetros, e a URL no browser não muda. Refresh refaz a requisição antiga.

o redirectTo faz redirecionamento do lado do cliente… é gerada uma outra requisição, e a URL do browser muda. Refresh continua na nova página.

L

ahmmm
rsrs então outra duvida… tem como eu saber de onde está vindo a request direto usando vraptor? ou eu teria que colocar um parametro na url por exemplo para identificar ?
por exemplo, se tá vindo de um redirect, ou de um acesso direto ao link??

mtooooo obrigado como sempre :wink:

Lucas_Cavalcanti

se eh uma redirect interna (forward) dá pra saber sim…

o servidor coloca um parâmetro que é a url original num atributo do request… não lembro direito qual eh o nome do atributo, mas se vc imprimir o nome de todos é um que tem forward e uri no nome

(httpServletRequest.getAttributeNames())

agora saber se é de um redirect externo, que volta no browser e faz outra requisição, é um pouco mais difícil, nem sei se dá pra saber genericamente…

pra que vc quer saber isso?

L

é que eu tenho a seguinte action

@Path("/evento/popupCadastrarComentario/{evento.idEvento}")
    public void popupCadastrarComentario(Evento evento){
        if(!usuarioWeb.isLogado()){
            result.redirectTo("/assinante/popupLoginPeloEvento/" + evento.getIdEvento().toString());
        }
    }

ai quando ela vai para a parte de login, o usuário volta tudo certinho até ai…
o que eu preciso saber, é se a chamada dessa action está vindo do login, por que eu estou abrindo ela em uma modal, então se eu fiz login, eu tenho de dar um refresh na página (na verdade é uma sexylightbox que abre dentro de uma iframe rs)

então por isso preciso saber, se popupCadastrarComentario tá sendo chamada do sexylightbox, ou se tá vindo de um redirect de popupLoginPeloEvento

entende ?
rsrs mta gambiarra isso q to fazendo ? rsrs

Lucas_Cavalcanti

vc precisa saber isso só dentro do popup, certo? pra dar um refresh na página que abriu, certo?

tenta fazer isso via javascript com window.opener… se vc tah em uma popup, essa variavel não é undefined

de qqer forma, isso eh meio gambiarra sim :wink:

L

hummm então…
o sexylightbox do mootools quando abre uma modal em modo iframe…
sempre vou ter window.opener == undefined, para acessar a página de fundo tenho de usar window.parent…
a idéia de identificar de onde vem a chamada para a action, é adicionar um result include chamando um javascript que irá fazer um refresh da window.parent
até agora só estou usando o result.redirect, vou experimentar fazer um result.forward da login para cadastraComentario, e ver se eu acho aquele campo que tu comentou…
rsrs daqui a pouco a preguiça vai bater vou mandar um ?isFromLogin=true e a só na xuribibaaaa

rsrsrs

L

consegui…

Boolean vemDoLogin = false;
        if (requestInfo.getRequest().getHeader("referer") != null) {
            vemDoLogin = requestInfo.getRequest().getHeader("referer").contains("popupLoginPeloEvento");
        }
        result.include("vemDoLogin", vemDoLogin);

na action popupLoginPeloEvento usei redirectTo mesmo…

Lucas_Cavalcanti

só cuidado, pois o referer não funciona em todos os casos

L

humm…
todos os casos nessa mesma action ?
ou seria outro cenário?

por que eu joguei uma verificação para ver se referer != null antes de utilizar né… então acho que estaria seguro…

Lucas_Cavalcanti

é só pra ter em mente que ele vai vir null às vezes… o seu if já previne bem :wink:

[]'s

Criado 1 de julho de 2010
Ultima resposta 18 de ago. de 2010
Respostas 45
Participantes 5