Duvida VRaptor : Camadas

21 respostas
T

Olá pessoal… estou tendo uma duvida com o VRaptor…

Tenho varios relatorios para fazer, e queria poder chamar uma logic só para todos, e dentro dessa logic, chamar o metodo q efetivamente cria o relatorio.
Isso do jeito q ta agora ate funcionaria, mas queria fazer de algum jeito que nao usasse um “if” para cada relatorio novo que eu adicionasse.
Da forma como estou pensando, passaria um atributo a mais para a logic, com o nome do relatorio q quero gerar, e uma sequencia de if e else definiria qual metodo vai ser chamado apartir deste atributo.

Mas puts… fazer desse jeito esta zuado… tem q ter algum jeito melhor de fazer isso…
Ahh, estou usando um metodo validate tbem, fazendo algumas validacoes antes de chamar a logic em si…

Alguem tem alguma ideia geniosa?

AbraXXX

21 Respostas

Lucas_Cavalcanti

Jeito “fácil”:

cria uma enum com um método que retorna um objeto que gera o relatório:

public enum TipoDeRelatorio {
    public abstract Relatorio getRelatorio();

     TIPO1 {
           public Relatorio getRelatorio() {
                return new RelatorioTipo1();
          }
     }, TIPO2 {...}, ....    
}

e na lógica

public void geraRelatorio(TipoDeRelatorio tipo) {
          tipo.getRelatorio().gera();
}

como é uma enum, vc pode receber na requisição:
tipo=TIPO1

e vai vir o tipo certo…

ok?

T

hum… olha… parece realmente melhor do q a ideia do if…
mas de qualquer forma, nao sera feita uma verificacao em tipo por tipo quando eu passr isso pro enum?
acho so q o enum é mais rapido q o if, mas ainda sim, vai dar mt codigo pra escrever e terei sempre que criar um tipo enum cada vez q colocar um relatorio novo…

nao sei… talvez eu nao tenha pegado direito oq vc disse…
mas obrigado pela ajuda assim mesmo… quebrando a cuca aqui…

Lucas_Cavalcanti

o enum não precisaria ter soh isso… mas seria algo do tipo…

outra saída, talvez um pouco mais complicada:

crie uma interface Relatorio que gera os relatórios…

crie um converter pra Relatório assim:

@Component
@Converts(Relatorio.class) //vraptor 3
public class RelatorioConverter implements Converter<Relatorio> {
    public Relatorio convert (String value, ...) {
           Class<? extends Relatorio> type = Class.forName(value);
           return type.getConstructor().newInstance();
    }
}

daí vc recebe na requisição algo do tipo:

relatorio=br.com.seuprojeto.MeuRelatorio

e tendo uma classe com construtor vazio:

public class MeuRelatorio implements Relatorio {..}

Dá pra simplificar um pouco fixando o pacote base dos relatórios… mas seria algo assim a idéia

[]'s

T

valeuzao lucas… vou tentar dar uma digerida nisso aqui…
será q vc podia tentar explicar a solucao do enum um pouco melhor? acho q ao entendi muito bem… sou novatinho tanto no vraptor quanto em web… :oops:
pq tipo… eu estou passando de volta de uma funcao javascript o atributo q define qual funcao eu vou chamar…
como eu faria? teria q voltar uma string que seria um tipo do enum, é isso? dai dentro da logic eu crio um enum e passo pra ele o tipo… e dai quando ele inicializar ele chama a funcao q eu quero… é isso?

vo ter q dar uma lida sobre enums… eu nunca relamente usei um… :lol:

Lucas_Cavalcanti

Vc não precisa criar a instancia do enum, o vraptor já faz isso pra vc:

se vc tiver uma enum:

public enum Animal {
    CACHORRO, GATO, COELHO
}

e receber na sua lógica

public class MeuController {
   public void minhaLogica (Animal animal) {
   }
}

você pode receber na requisição tipo
http://localhost:8080/meuProjeto/meu/minhaLogica?animal=GATO

e o vraptor vai passar para a sua lógica o valor da enum Animal.GATO

no caso da enum de relatórios, vc pode dar nomes pros valores da enum e fazer o vraptor se virar qual é a enum que ele vai colocar na sua lógica…

entendeu como funcionaria?

T

Opa lucas… tá bem mais claro na minha cabeça agora…
Nao estou acostumado com framework… lol… deixa as cioisas bem mais faceis realmente…

Mas entao… dai eu recebo o enum na logic… vai ser já um enum carregado com o tipo de relatorio que deve ser gerado… ex…
sendo Relatorio o nome do enum, vou ter um Relatorio.TIPO1 que seja…
Dai oq eu vou ter q fazer dentro da declaracao do enum é fazer ele implementar um metodo q é generico para todos os itens enums… so q cada tipo vai ter sua propria implementacao… e nessa implementacao eu chamo o metodo que gera efetivamente o relatorio… é isso?

hehehe espero que tenha entendido… pelo q eu me lembro de enums, é isso que vc sugeriu

Lucas_Cavalcanti

isso, cada tipo dentro da enum vai implementar a geração de um relatório diferente… daí vc chama genericamente dentro da sua lógica…

T

valeuzao lucas… vo fazer desse jeito mesmo… se der tudo certo eu te falo depois… hj ainda tou fazendo os relatorios… hhehehehe

Muito obrigado pela ajuda! MESMO!

AbraXXX :lol: :roll:

T

Opa! Lucas... da mais uma mao com o VRaptor cara...
pra eu chamar o metodo que gera o relatorio, eu tenho q deixar o metodo static... mas eu nao posso pq tem uns atributos dentro q nao me deixam fazer isso... ai tentei instanciar a propria classe logic, mas ela tem q ser instanciada passando um objeto DAOFactory...
q q eu faço? me falaram q nao é bom eu criar uns construtor q nao recebe argumentos...
e eu to fazendo isso certo? sera q eu devia isolar os metodos que criam relatorios em outra classe separada e importar essa classe na logic, onde o enum ta declarado?

meu enum ficou assim :
enum Relatorio{ 
		RECIBO , 
		FATURACOMISSAO{
			public boolean generateReport(HashMap parameters){
				
				return new RelatorioLogic().exportarXLSRelacaoRecibo(
						(Long)parameters.get("idContratante"),(String)parameters.get("carteiras"), 
						(String)parameters.get("filiais")	 ,(Date)parameters.get("periodoData1"), 
						(Date)parameters.get("periodoData2") ,(Long)parameters.get("idAssessoria")
						);
			}
		};
		public boolean generateReport(HashMap parameters){
			return false;
		}
		
	}

que q c acha cara? é mais uma duvida sobre boas praticas com VRaptor q qualquer outra coisa...
to sentindo q to fazendo mt gambiarra,... queria deizar isso mais generico... mais bonito...
tals...
Aguardo sua ideia... abraço!

Lucas_Cavalcanti

o que vc precisa para gerar o relatório?
-Dao, Parâmetros, etc?

é soh receber isso como parâmetro do método da enum…

public boolean generateReport(DaoX dao, HashMap parameters) {

}

e da lógica vc consegue passar essas dependências pra enum…

T

Opa… conseguyi fazer tudo funcionar lucas… preparei uns 3 relatorios…
Agora vem a má noticia…
Minha arquitetura esta assim:
Cada relatorio tem uma JSP, para pegar os dados especificos do relatorio.
Todos os relatorios estao sendo enviados para o mesmo metodo (geraRelatorio.logic) e redirecionados para o validate respectivo dele (validateGeraRelatorio)…
Quando eu nao acho nada para colocar no relatorio, eu preciso voltar com uma msg pra tela dizendo que nao foram encontrados dados… e deixar o usuario faezr uma nova procura, na jsp de origem…

O problema é: a pagina de retorno do validate tem q ser configurada no view.properties né? como eu vou fazer para ele retornar para a JSP de origem, e nao sempre para uma pagina padrao? Vou me matar disserem que nao tem jeito…
Eu nao tinha lembrado disso… so quando fui testar gerar relatorios sem dados que fui ver…

Agradeço a ajuda…
Salva ae lucas… :lol:

Lucas_Cavalcanti

se a geração do relatório for feita por um link na página, a maioria dos browsers coloca um header
na requisição chamado Referer… que é a página onde está o link…

vc tem que capturar isso de algum jeito e usar no redirecionamento…

T

mas usar o validate, nao quer dizer q ele obrigatoriamente vai ter q redirecionar para a pagina invalid q eu configurei no view.properties? Se nao, onde e como no metodo validate, quando eu souber q tenho um erro em maos, redireciono isso pra jsp q eu quero?

esse referer da pra pegar na propria jsp e passar como parametro pro metodo gerarRelatorio, né? eu posso ate passar o endereço q ele tem q voltar… so nao sei como mandar o metodo validate fazer isso…

e sim… eu uso um botao mesmo pra gerar o ralatorio… deve dar pra fazer oq vc ta falando… só nao sei como… lol
tava dando uma lida na documentacao no VRaptor sobre validators, mas eles lá usam de um jeito diferente do q eu to usando, acho…

:shock: to confuso… hahaha lol :lol:

Lucas_Cavalcanti

Você pode passar um parametro pagina para a lógica (passando o document.location.href de dentro do jsp ou algo do tipo),
e tentar fazer algo do tipo no views.properties:

geraRelatorio.invalid = ${pagina}

não tenho certeza se funciona, esse pagina tem que estar disponível via getter ou @Out

T

Já estou tentando dessa forma… apesar de estar meio incredulo… nao acho q o properties vai reconhecer uma variavel lá…
Onde estao os criadores do VRaptor quando se precisa deles… :lol: :lol: :lol:
Jájá posto se funfou…
Devo fazer tudo usando strings mesmo né? passa o endereço pro metodo, seta um avriavel que vai estar marcada como @out na classe do metodo com a string que contem o endereço e coloca no properties essa mesma variavel… é isso né?

Lucas_Cavalcanti

Você pode migrar pro VRaptor3… é bem mais fácil fazer isso que você está querendo:

http://vraptor.caelum.com.br/documentacao/migrando-do-vraptor2-para-o-vraptor3/
http://vraptor.caelum.com.br/documentacao/vraptor3-o-guia-inicial-de-10-minutos/

eu sou um dos desenvolvedores :wink:

T

po lucas… vou seguir seu conselho, pq pelo q tenho lido o VRaptor 3 ta bem melhor mesmo…
Mas vo ter q me virar com esse agora… o projeto inteiro ja ta com o velho… meu GP me mata se eu falar um trem desse pra ele… hahaha

deixa te falar… so pra ver se estou fazendo certo…
estou mandando uma string com o endereço que deve ser redirecionado… blza… recebo isso no metodo validateGeraRelatorio…
Criei entao uma variavel na classe q ta segurando o metodo de validar… pus a tag out nela… ficou assim :

@Out(scope=ScopeType.REQUEST) public String redirectPage;

ai atribui a string q recebi da jsp ao redirectPage… huahauha seilá se isso ta certo… huahauha :lol: :lol: :lol:

dai no view.properties pus assim :

# Componente Relatório relatorio.gerarRelatorio.invalid = ${redirectPage}

mas ae as duvidas… q q eu faço com os errors do validate? mesmo esquema? adiciona alguma coisa se der erro? acho q sim né… o resto acho q nao muda nada… o esuqema é ver se o properties vai conseguir ler a m!@@#$ da variavel… :?

Lucas_Cavalcanti

o views.properties lê as variáveis sim…
só não sei se dá pra usar a variável pra dizer qual eh a página… (eu só usei pra setar parâmetros adicionais)

T

Nao funcionou… buaaaaaaaaaaaaaaaaaaaaaaaaaaaa
As minhas declaracoes estavam corretas né?
Deu pagina nao encontrada… previsivel… mas esperança é a ultima q morre…
que q eu faço agora? q q eu vou dizer pro meu GP? ahhhhhhhhhhh :cry: :lol:

bom… fudeoooo nao tenho mais ideias…

se alguem puder me dizer qualquer gambiarra q eu possa fazer, sou grato!!

Lucas_Cavalcanti

bom, vc pode fazer isso não via validateblah

cria uma lógica, receba o HttpServletResponse e faça os redirecionamentos na mão…

response.sendRedirect(url)
ou response.getRequestDispatcher(url).forward(…)

pode ser que vc tenha que anotar a lógica com @Viewless ou algo do tipo…

T

Eu ja tinha tentado isso… eu acabo recebendo uma exception q nao consigo tratar… o programa acabava fazendo dois flush, e ja viu oq isso dá né… :frowning:
Mas eu devo ter feito algo errado…

Quer dizer entao q eu devo abandonar o metodo validate e fazer tudo dentro do logic mesmo?
Se tivesse um jeito de dentro da logic ou do validate da logic mandar já o programa retornar para apagina q eu quero, setando alguns parametros a mais no response, seria lindo… mas quando fiz isso recebi a exception q eu te disse…

vou dar uma olhada aqui se consigo fazer denovo… dai explico melhor esse erro…

Valeu pela ajuda lucas! e boa sorte com o VRaptor3!!!

Criado 22 de setembro de 2009
Ultima resposta 25 de set. de 2009
Respostas 21
Participantes 2