[APOSTILA] Tutorial JAVA com JSF 2.0, Facelts, Hibernate (JPA) , Spring 3.0 e PrimeFaces

Parabéns meu caro. Muito boa. Valeu mesmo.

Muito legal tua apostila, mas como faço para baixar a pasta “libs do CODE” que cita na configuração do projeto?

o CODE é um repositório SVN, vc precisa de um client pra baixa tudo ok, o que uso é o TURTOISE, muito bom e baixa tudo ok, mas la pelo site do code msm, vc baixa acho que “raw file” e traz cada .jar, mas aconselho baixar um client SVN.

Obrigado, Diego.
Abraços.

muito obrigado pela apostila
está ajudando muito

Que bom que ressuscitaram esse tópico,

vai ser de grande ajuda essa apostila, parabéns pela iniciativa Wolky.

Antes de mais nada muito obrigado Wolky pelo tutorial excelente!

Eu estou com um problema na aplicação. Troquei o driver e referencias para o banco mysql.
em jdbc

driverClassName=com.mysql.jdbc.Driver

em spring.xml

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

Eu cheguei ao ponto de desistir de conferir e copiei todo o projeto para não ter chance de erros!

Tive problemas para baixar as lib do site “CODE”, sempre viam com tamanho de 29kb, mas depois baixei com o Orbit os tamanhos estão batendo. (caso alguem possa subir elas completas eu estaria mais seguro quanto a isso. :slight_smile: )

Bem vamos ao erro. Eu consigo gravar o reino, mas quando clico em listar ele só me mostra um reino sem nome que o botão editar( abre o editor, mas não grava) e excluir não funcionam e me retornam o erro:

javax.servlet.ServletException: /pages/CadReino.xhtml @51,53 value="#{reinoMB.entity.reino}": Target Unreachable, 'entity' returned null
e

javax.servlet.ServletException: java.lang.IllegalArgumentException: attempt to create delete event with null entity javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)

A busca depois que alguma parte dá erro não funcionar e quando funciona só me traz resultado se eu souber o reino que quero procurar:

javax.servlet.ServletException: /pages/CadReino.xhtml @51,53 value="#{reinoMB.entity.reino}": Target Unreachable, 'entity' returned null javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)

O botão filo não funciona depois de dar algum erro. Antes de dar erro ele não lista, não busca e o gravar não mostra os reinos cadastrados.

vou anexar os txt dos erros completos.

---------------------------------------------------------------------EDIT---------------------------------------------------------------------------------------
Uma coisa que eu acho que pode ser, o modo de busca do SQL é diferente do MySql?? Porque com eu disse(mas não expressei bem), quando eu clico em listar ele aparece um item só, que o botão editar e excluir não funciona. O que aparenta ser para mim é que ele não tá listando, então o editar, excluir e selecionar do filo não abre! Vou procurar sobre isso se conseguir algo eu posto. :?

Primeiramente queria agradecer a todos os leitores pelos elogios e que bom que o tutorial o estão ajudando.
Segundo queria pedir desculpa pela demora em responder rpsouza, ando muito ocupado. Você fez muitas perguntas e citações, então vou respondendo por partes.

[quote=rpsouza441]Antes de mais nada muito obrigado Wolky pelo tutorial excelente!
Tive problemas para baixar as lib do site “CODE”, sempre viam com tamanho de 29kb, mas depois baixei com o Orbit os tamanhos estão batendo. (caso alguem possa subir elas completas eu estaria mais seguro quanto a isso. :slight_smile: )
[/quote]
O CODE tem um probleminha de baixar arquivos pesados pelo próprio site, para baixar os arquivos de forma segura é bom utilizar um CLIENT SVN, eu recomendo o Turtoise.

Se não me engano, esse erro é que não foi instanciado o Reino, não tem valor nenhum la na entidade então não é possivel relacionar os campos, isso deve ser analisado no botão editar/listar que tem a tag <f:setPropertyActionListener /> responsável por pegar a entidade selecionada na lista e passar para o atributo que representa uma só entidade (em vez da lista) na visão.

O arquivo anexado busca.txt contém o erro:

javax.servlet.ServletException: java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key ----eRRo-----_Busca javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
esse erro é porque no arquivo messages.properties não tem a chave ----eRRo-----Busca… Se não me falha a memória, o fluxo desse erro é o seguinte: você pediu para efetuar a busca, mas não digitou nada para ser buscado, lá no validador não deixo chamar a ação se você não passou nenhum valor, setando uma mensagem na visão de que: “Você tem que digitar algum valor de busca” ou algo parecido, lembro também que toda mensagem de erro eu busco no bundle pela chave erro{nomeDoErro} sendo que erro_ é fixo, e {nomeDoErro} vem como parametro, no meu caso minha mensagem de erro tem a chave: erro_Busca, e esse erro descreve exatamento que você não tem a chave: ----eRRo-----_Busca no bundle

O arquivo editar.txt é o erro que citei mais acima e no arquivo deletar.txt segue o mesmo padrão de erro do editar, é problema na tag <f:setPropertyActionListener />
pode ser o ciclo do JSF também, as vezes você está chamando a função de editar/deletar primeiro que a do <f:setPropertyActionListener /> fazendo com que esteja null a entidade não podendo executar a ação.

Indico você ler um pouco sobre ResourceBundle/internacionalização via arquivo .properties para corrigir o erro do busca.txt
Se não conseguir, preciso de mais detalhes, estou andando muito sem tempo e estou mexendo com 4 projetos, não me lembro muito bem do fluxo da arquitetura do tutorial que escrevi, se possível, envie o .war com código fonte por e-mail para analisar melhor

Obrigado pela resposta, e sai dessa de pedir desculpa. Fico muito feliz de vc ter vir aqui para me ajudar :smiley:

Nossa na busca eu vacilei feio! Eu tinha colocado esse —eRRo— pra eu poder identificar mais facil quando saisse a tela de erro! Não me passou pela cabeça do tratamento do erro pelo jsf, vou ler mais sobre ResourceBundle. :oops:

Quanto as outras funções, eu até fiz edit aqui no post para dizer que estava achando que de alguma forma não estava buscando a entidade. Será que muda os “search’s” do hibernate por mudar de sql para mysql? Tudo que eu alterei no projeto foi esse eRRo, as especificações (que mostrei) para o hibernate conectar no mysql e o pacote do projeto de br.ueg.portal para br.com.tutorial.

Corrigi o —eRRo— e agora o JSF lança a mensagem na tela.

Anexei o war sem a lib.

[quote=rpsouza441]
Quanto as outras funções, eu até fiz edit aqui no post para dizer que estava achando que de alguma forma não estava buscando a entidade. Será que muda os “search’s” do hibernate por mudar de sql para mysql? Tudo que eu alterei no projeto foi esse eRRo, as especificações (que mostrei) para o hibernate conectar no mysql e o pacote do projeto de br.ueg.portal para br.com.tutorial.

Anexei o war sem a lib.[/quote]

Essa busca eu vou ver direitinho o problema dela mais tarde, hoje a noite executo o war e vejo qual o problema pra ti e te mando resposta no máximo até amanhã.
Em questão do hibernate, ele foi feito para executar qualquer SQL independente de qual banco de dados você use, se no dialeto vc disse que é o MySQL o próprio hibernate tem que se virar e criar uma sql executavel pelo MySQL, então não acho que seja o hibernate, de todo jeito, quando for analisar o projeto vou debugar ele e ler a sql que está gerando, tenho o mysql aqui tb e vou tentar executar ela direto no banco para tirar essa sua dúvida.

Com muita vergonha eu digo que o problema foi a minha alteração do termo “erro_” para “eRRo_” pq eu queria achar facilmente o erro na tela, e não tinha prestado atenção sobre o ResourceBundle.
Agora o problema de não estar rodando o projeto é por causa do meu computador! :oops: Testei em outros dois computadores e eles rodaram perfeitamente. Eu já desinstalei e instalei, coloquei versão 64b e 32b e nada! Só me resta formatar…

Muito Obrigado Wolky pelo tutorial e por esclarecer minhas duvidas! 8)

vi a apostila meio por cima, e gostei… vou ler ela e acompanhar no final de semana com mais tempo…

eu estou precisando fazer um projeto na faculdade e preciso implementar um sistema de autenticação… seria possível implementar neste “projeto” da apostila?
iria precisar de muita coisa?

[quote=alandiniz]vi a apostila meio por cima, e gostei… vou ler ela e acompanhar no final de semana com mais tempo…

eu estou precisando fazer um projeto na faculdade e preciso implementar um sistema de autenticação… seria possível implementar neste “projeto” da apostila?
iria precisar de muita coisa?[/quote]

Sistema de autenticação é a coisa mais simples de se fazer, ainda mais nesse projeto,
você tem a opção de fazer essa atenticação com o Spring Security ou com Spring AOP, os dois necessitam estudo e pode ser um pouco complexo, mas dominando-os são otimos sistemas de autenticação, com bastante segurança (principalmente o Spring Security)
Porém, como se trata de um projeto de faculdade, te recomendo fazer um sistema de autenticação com Filter, você apenas cria uma classe que extende Filter e verificar se ele está tentando acessar alguma pasta de arquivos que somente quem deve estar logado deva acessar, se eles estiver tentanto, você redireciona ele para o login (caso não logado), caso logado deixa passar.
Vá no web.xml e fale que ele é um filtro pra pasta citada
Segue um exemplo que fiz para um projeto da faculdade, o nome do projeto era RCDEx e não permitia ele a acessar nada que estava dentro da pasta “pages”, ou seja, unica pagina que podia acessar era a index e a login que ficavam fora de “pages”:

package br.com.rcdex.view.servlets;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import br.com.rcdex.model.Usuario;

/**
 * Filter for login, any access for all pages, come to this filter.
 * 
 * @author Diego
 * 
 */
public class LoginFilter implements Filter {

	@Override
	public void destroy() {
	}

	/**
	 * Method that filter the request and if logged, continue with the request,
	 * if not force the user to login.
	 * 
	 * @param ServletRequest
	 *            , ServletResponse, FilterChain
	 */
	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;

		HttpSession session = request.getSession(true);
		if (session.getAttribute("uri") == null) {
			String uri = request.getRequestURI().toString().split("/RCDEx/")[1];
			uri = uri.split(".jsf")[0];
			session.setAttribute("uri", uri);
		}

		if (!this.isLogged(request)
				&& !request.getRequestURL().toString().contains("login.jsf")) {
			response.sendRedirect(request.getContextPath() + "/inicio.jsf");
		} else {
			try {
				chain.doFilter(req, resp);
			} catch (Exception e) {
				response.sendRedirect(request.getContextPath() + "/inicio.jsf");
			}
		}

	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	/**
	 * Method that verify if user is logged
	 * 
	 * @param HttpServletRequest
	 * @return if the user is logged or not
	 */
	private boolean isLogged(HttpServletRequest request) {
		boolean retorno = false;
		HttpSession session = request.getSession(true);
		if (session != null) {
			Usuario usuario = (Usuario) session.getAttribute("usuario");
			if (usuario != null) {
				retorno = true;
			}
		}
		return retorno;
	}

}

E no web.xml:

<filter>
    <filter-name>Login Filter</filter-name>
    <filter-class>br.com.rcdex.view.servlets.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>Login Filter</filter-name>
    <url-pattern>/pages/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>

Espero ter ajudado,

E rpsouza, precisando é só falar

Olá Wolky, obrigado pela sua resposta :smiley:

poderia esclarecer algumas dúvidas, de possível?

1- o que significa “uri” ?

2- nessa linha Usuario usuario = (Usuario) session.getAttribute(“usuario”);
Obviamente eu tenho que ter uma classe de entidade Usuario.class, mais como realmente funciona akele metodo ali de login… o que significa o getAttribute(“usuario”); quais os atributos ele precisa ter?

----edit------esqueci de mencionar—
o site vai ter 3 níveis (roles)
1-publico que eh a pasta raiz
2- usuário registrado que vai ser /user
3- admin que tem acesso a /adm

URI é o endereço do site, por exemplo, o meu endereço do projeto era localhost:8080/RCDEX/ (isso é a index que ficava fora do pages)
a URI retorna /RCDEx, se tiver na URI o /pages é que ele está tentando acessar páginas que devem ser para usuários autenticados.

Cara eu só mostrei a lógica de se fazer um Filtro, tem muito mais coisa ai, Usuário é uma classe POJO que eu criei para espelhar o banco de dados, o getAttribute é um método do HttpSession, que vai na sessão e busca pelo atributo que você passou por parâmetro, nesse caso, eu busco na sessão o “usuário” e ele traz uma instancia do mesmo já que eu o setei.
Os métodos estão comentados, o isLogged ve se o usuário está na sessão, se estiver é e for o mesmo que ele está digitando, é que ele já está logado, então não precisa passar pelo filtro
o resto é com o doFilter, se não estiver compreendendo ainda, esse site explica bem legal como usá-lo: http://www.devmedia.com.br/utilizando-servlet-filter-com-javaserver-faces/5331

O controle você irá fazer dentro do doFilter, verificar de onde está vindo, uma dica é por exemplo, criar no banco um atributo booleano que representa se ele é admin ou não, quando você trazer o usuário do banco você verifica esse booleano se ele estiver tentando acessar uma página de admin, se ele estiver false, então não deixe ele entrar.

Tente ler mais sobre o Filter, o resto é lógica

Valeu Mestre.

Abs.

Nossa essa parada de validação era o próximo assunto que iria pesquisar para aprender! vlw Wolky

Eu to quebrando a cabeça com uma função que estou tentando colocar. Eu transportei o programa para uma inscrição.
Está com 3 tabelas. Curso, inscrito e inscrição(ManyToMany sem atributos, tem uma PK e duas FK de curso e inscrito).
Eu estou tentando fazer é: o inscrito digita o CPF e esse é validado (achei no GUJ um código que faz isso) e se existir esse CPF no banco abre o “formCad” em modo editar senão abre em modo adicionar.

A minha dificuldade é dizer para o jsf que essa busca é para abrir o editar da entidade, pois o find que o jsf usa mostra uma lista dos encontrados(como já passou pelo validador de cpf só pode existir um).
Alguém tem alguma dica de como consigo fazer isso?

====================EDIT=========================

Pensei em uma solução, foi fazer no jsf a validação do que acontecer, vai ser mais menos assim:

if(CPF = ok) abre a pagina de cadastro

na pagina de cadastro:

if(find.CPF = ok) abre a "busca" do inscrito (output) else abre o cadastrar inscrito (input)

Deve existir outra forma mais limpa, mas essa vai servir :lol:

:roll: as vezes eu caio tão fundo que esqueço do básico

Cara me desculpa por tanta duvida, mas já pesquisei e não consegui achar nada.

Tem como fazer um tabela com chave primaria composta nesse modelo?
Como a entity tem que ter a getId(), eu tropecei e não sei o que fazer

Boa Iniciava, to fazendo o download agora pra conferir o material, muito obrigado…

[quote=rpsouza441]Cara me desculpa por tanta duvida, mas já pesquisei e não consegui achar nada.

Tem como fazer um tabela com chave primaria composta nesse modelo?
Como a entity tem que ter a getId(), eu tropecei e não sei o que fazer[/quote]

Sim, você criar uma nova classe Entity que adeque ao seu modelo, por exemplo:
Crie a ComposedEntity que extende Entity, dentro dela você crie um atributo lá que represente sua segunda (ou mais) chave primária, ai vai de você verificar se há a necessidade de criar um controlador novo para isso
Esse é um caso que foge a regra padrão do exemplo, basta então adicionar as novas “regras de negócio”, que herda o que era pra ser utilizado e adiciona os métodos específicos, todo jeito você também terá que criar um ComposedManagedBean para saber controlar e editar essas chaves primárias.

O foco da arquitetura (mesmo sendo muito simplória) é que seja necessário criar apenas o modelo e a visão para fazer CRUD simples, as novas regras herdam as classes “genéricas” e adicionam suas especificidades. Como você pode ter mais de um entidade com chave composta, crie a classe abstrata para ela.

Agora andei lendo sobre chave composta (não costumo utilizar) e pessoal vem reclamando dela no hibernate, de uma olhada nesses comentários:


http://javafree.uol.com.br/topic-5839-Chave-composta-no-mapeamento-HIbernate.html

E desculpe pela demora em responder