Aplicação Web Completa JSF EJB JPA JAAS

View – ManagedBeans

Vamos criar agora os ManagedBeans.

Vamos adicionar o projeto EJB ao projeto web. Botão direito sobre projeto JSF > Properties

Java Build Path > Projects > Add > Check CrudEJB > OK

Primeiro, crie o DogMB:

package com.mb;

import java.util.List;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import com.facade.DogFacade;
import com.model.Dog;

@ManagedBean
@RequestScoped
public class DogMB {

	@EJB
	private DogFacade dogFacade;

	private static final String CREATE_DOG = "createDog";
	private static final String DELETE_DOG = "deleteDog";
	private static final String UPDATE_DOG = "updateDog";
	private static final String LIST_ALL_DOGS = "listAllDogs";
	private static final String STAY_IN_THE_SAME_PAGE = null;

	private Dog dog;

	public Dog getDog() {

		if(dog == null){
			dog = new Dog();
		}

		return dog;
	}

	public void setDog(Dog dog) {
		this.dog = dog;
	}

	public List<Dog> getAllDogs() {
		return dogFacade.findAll();
	}

	public String updateDogStart(){
		return UPDATE_DOG;
	}

	public String updateDogEnd(){
		try {
			dogFacade.update(dog);
		} catch (EJBException e) {
			sendErrorMessageToUser("Error. Check if the weight is above 0 or call the adm");
			return STAY_IN_THE_SAME_PAGE;
		}

		sendInfoMessageToUser("Operation Complete: Update");
		return LIST_ALL_DOGS;
	}

	public String deleteDogStart(){
		return DELETE_DOG;
	}

	public String deleteDogEnd(){
		try {
			dogFacade.delete(dog);
		} catch (EJBException e) {
			sendErrorMessageToUser("Error. Call the ADM");
			return STAY_IN_THE_SAME_PAGE;
		}			

		sendInfoMessageToUser("Operation Complete: Delete");

		return LIST_ALL_DOGS;
	}

	public String createDogStart(){
		return CREATE_DOG;
	}

	public String createDogEnd(){
		try {
			dogFacade.save(dog);
		} catch (EJBException e) {
			sendErrorMessageToUser("Error. Check if the weight is above 0 or call the adm");

			return STAY_IN_THE_SAME_PAGE;
		}		

		sendInfoMessageToUser("Operation Complete: Create");

		return LIST_ALL_DOGS;
	}

	public String listAllDogs(){
		return LIST_ALL_DOGS;
	}

	private void sendInfoMessageToUser(String message){
		FacesContext context = getContext();
		context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
	}

	private void sendErrorMessageToUser(String message){
		FacesContext context = getContext();
		context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
	}

	private FacesContext getContext() {
		FacesContext context = FacesContext.getCurrentInstance();
		return context;
	}
}

Observações sobre o código acima:

  • Toda a navegação se encontra no arquivo faces-config.xml. Utilize constantes ou então um Message Bundle com a navegação das suas páginas, será melhor do que deixar a chave de cada navegação espalhada pelo seu código.
  • Veja que está sendo utilizado apenas @EJB para injetar o EJB dentro do MB. Esse modo funciona pois estamos fazendo deploy de tudo dentro do mesmo EAR. O JBoss 7 facilita essa localização.
  • Caso no JBoss 6 não funcione a injeção do EJB (ou caso você utilize fora do EAR) utilize a anotação do seguinte modo: @EJB(mappedName=“DogFacadeImp/local”).
  • Note que é exibida uma mensagem para o usuário. Foi feito um try/catch para cada ação feita no Façade, caso ocorra algum erro em alguma ação é enviada uma mensagem de erro ao usuário.
  • O correto seria validar o dado tanto no ManagedBean como no Façade. São validações que custam pouco (ou quase nada) do seu processador.
  • Caso você esteja utilizando o JBoss 4 você terá que fazer o JNDI lookup conforme o código abaixo (lembrando que conforme dito na página de criação do EJB desse post, utilize a anotação LocalBinding). Basta anotar sua classe assim:
    @Stateless
    @LocalBinding(jndiBinding="MyBean")
    public class MyBeanImp implements MyBean{
    	@Override
    	public String hello() {
    		return "Value From EJB";
    	}
    }
    // In your Servlet class you would lookup like the code bellow:
    public class Inject extends HttpServlet {
    
    	private MyBean local;
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		try {
    			InitialContext iniCtx = new InitialContext();
    			local = (MyBean) iniCtx.lookup("MyBean");
    		} catch (NamingException e) {
    			e.printStackTrace();
    		}
    
    		System.out.println(local.hello());
    		request.getRequestDispatcher("/finish.jsp").forward(request, response);
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    	}
    }

Vejamos agora o código do UserMB:

package com.mb;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import com.facade.UserFacade;
import com.model.User;

@SessionScoped
@ManagedBean
public class UserMB {
	private User user;

	@EJB
	private UserFacade userFacade;

	public User getUser(){
		if(user == null){
			ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
			String userEmail = context.getUserPrincipal().getName();

			user = userFacade.findUserByEmail(userEmail);
		}

		return user;
	}

	public boolean isUserAdmin(){
		return getRequest().isUserInRole("ADMIN");
	}

	public String logOut(){
		getRequest().getSession().invalidate();
		return "logout";
	}

	private HttpServletRequest getRequest() {
		return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
	}
}

Observações sobre o código acima:

  • Esse MB é utilizado apenas para controlar o usuário na sessão. Você poderá utilizar esse MB caso precise exibir o nome do usuário ou até mesmo utilizar o usuário logado para qualquer outra ação.
  • Repare que é um MB de sessão, com isso é verificado apenas uma vez se o usuário está null, caso esteja, buscamos no banco de dados. Com isso, não precisamos ir  toda vez ao DB para buscar os dados do usuário.
  • Caso a injeção do EJB não funcione e você venha a ter algum erro, leia as observações do DogMB dicas que poderão te ajudar.

241 Thoughts on “Aplicação Web Completa JSF EJB JPA JAAS

  1. Marcos Filho on April 26, 2013 at 6:38 pm said:

    Olá Hebert, como ficaria esse protected T findOneResult(String namedQuery, Map parameters)

    e public User findUserByEmail(String email)

    sendo que em Hibernate, já rodei aqui para tentar implementar utilizando a mesma ideologia que vc usou mais até agora nao obtive sucesso.

    • uaihebert on April 29, 2013 at 7:35 pm said:

      Marcos, boa tarde.

      Do modo como se encontra no projeto ele está funcionando.

      Caso você tenha alguma exception após realizar alguma alteração poste o código no guj que ficará mais fácil de ajudar.

      Obrigado pela visita.

  2. Pingback: 1389 Ideias para aplicativos Android – GUJ | S60Aplicativos

  3. Roger on April 15, 2013 at 1:25 pm said:

    Hebert, boa tarde.

    Parabéns pelo post.

    Só uma dúvida. A estrutura que você propõe pode gerar um inconveniente na aplicação. Se você atualizar a página gerará um “re-post” no seu CRUD. Já pensou em implementar o padrão POST-Redirect-GET para resolver o problema?

    • uaihebert on April 20, 2013 at 8:21 pm said:

      Roger, boa noite.

      Esse patern é bom de ser utilizado, não o coloquei no post para não adicionar mais complexidade para quem está começando agora. [=

      Obrigado pela visita e pelo apoio.

  4. Cara parei na parte “adicione o EJB no JBoss”, adicionei, criei o crudDB no Postgres, executei o JBoss e nada, nenhuma tabela foi criada.
    Sou iniciante, segui todos os passos certinho até aqui, mas não deu certo.
    Eu uso Linux, Eclipse Indigo, JBoss 7 e Postgres 9.1.18

  5. Marcos Fontana on March 18, 2013 at 4:41 pm said:

    Hebert, boa tarde.

    Estou recebendo o seguinte erro quando autenticado pelo servidor:

    HTTP Status 408 – The time allowed for the login process has been exceeded. If you wish to continue you must either click back twice and re-click the link you requested or close and re-open your browser.

    Já procurei algumas soluções e nada de me ajudarem. Teria alguma solução mais explicita para aumentar o tempo de sessão para o Login? (acho que é esse o problema).

    Obrigado!

    • uaihebert on April 4, 2013 at 8:17 pm said:

      Marcos, boa noite.

      Nunca tomei esse erro.

      Baixe o projeto aqui do post e tente executá-lo.

      Obrigado pela visita.

  6. Só pra complementar na linha 58 do código:
    Query query = em.createNamedQuery(namedQuery);

    // Method that will populate parameters if they are passed not null and empty
    if (parameters != null && !parameters.isEmpty()) {
    populateQueryParameters(query, parameters);
    }

    result = (T) query.getSingleResult();

    Existe sim um método tipado,
    TypedQuery javax.persistence.EntityManager.createNamedQuery(String arg0, Class arg1)

    • uaihebert on April 4, 2013 at 8:15 pm said:

      Diogo, boa tarde.

      Na época que criei esse post eu conhecia apenas o JPA 1.0 e não havia o método tipado.

      O TypedQuery veio com o JPA 2.0 que vim aprender algum tempo depois.

      Obrigado pela visita. [=

  7. Bruno on March 4, 2013 at 10:02 am said:

    Hebert, mais uma dúvida:

    No seu exemplo, listalldogs.xhml já estava no diretório protected, logo ao tentar acessar esta página o JAAS chama a página de login, que após validado já redireciona para a página desejada (listalldogs.xhtml). Porém, como faço, sendo a página de login a primeira por exemplo, para após o login, redirecionar para uma outra página qualquer?

    • uaihebert on March 4, 2013 at 12:37 pm said:

      Bruno, bom dia.

      Olhe no arquivo de web.xml tem o welcome-page que indica qual a página de login.

      Quando o usuário acessar http://localhost:8080/suaAplicacao após login ele será direcionado para a página demarcada lá.

      Caso você queira um controle mais refinado, como caso ADM envie para página A se for usuário para a página B, você teria que criar um módulo de JAAS.

      Até mais.

Comment navigation

 

Leave a Reply

Post Navigation