visibility of property set in #PostConstruct in ManagedBean - jsf

i am tryiing to get property value in my #RequestScoped Bean which is set in #PostConstruct. I have editUser page witch get userId from other page, and i am getting user from database in #PostConstruct, but when i try to edit that user in same page, user object is null, in method editUser.
Is there a way to get that object, which is set in PostConstruct?
Here is my EditUserBean:
package ba.nedim.colaborationtoolapp.model;
import ba.nedim.colaborationtoolapp.dto.UserDTO;
import ba.nedim.colaborationtoolapp.services.RegisterService;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import org.primefaces.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#ManagedBean
#RequestScoped
public class EditUserBean implements Serializable{
#EJB
private RegisterService userService;
private final Logger log = LoggerFactory.getLogger(EditUserBean.class);
private int idUser;
#ManagedProperty("#{param.id}")
private int actionId;
public int getActionId() {
return actionId;
}
public void setActionId(int actionId) {
this.actionId = actionId;
}
private UserDTO user = new UserDTO();
public UserDTO getUser() {
return user;
}
public void setUser(UserDTO user) {
this.user = user;
}
#PostConstruct
private void initialize(){
if(actionId!=0){
setUser(userService.getUserByID(actionId));
}
}
public void editUser(){
UserDTO user = getUser();
log.info("UserID:" + user.getIdusers());
}
private String gotoUserPage(){
return "users";
}
}

After the page has been fully rendered, the #RequestScoped bean is destroyed along with all its instance variables (including the user). I presume this is the point at which you then attempt to execute editUser() which results in an NPE.
Use a #ViewScoped bean instead, to ensure your instance variables survive a postback to the same view

Related

How to test a Controller and Model in a JSF Project with jUnit?

i don't know exactly how to write tests for these following Classes especially for the Controller and Model. Is it to possible to test with jUnit ?
I heard from Selenium but first i would test with jUnit. Thanks for ur help and best regards.
Controller.class:
import factory.InfoMessageFactory;
import entity.Product;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import model.ProductModel;
import project.Konstanten;
#Named(value = "ProductController")
#SessionScoped
public class ProductController implements Serializable {
private Product product;
#Inject
private ProductModel model;
#PostConstruct
public void init() {
this.product = new Product();
}
public String addProduct() {
this.model.newProduct(this.product);
}
public Product getProduct() {
return product;
}
public void setProdukt(Product product) {
this.product = product;
}
public List<Product> getProducts() {
return this.model.getProducts();
}
}
Model.class
package model;
import ejb.DB;
import entity.Product;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
#Dependent
public class ProductModel implements Serializable{
#Inject
private DB db;
public boolean addProduct(Product p){
try{
db.persist(p);
}catch(Exception e){
System.out.println("Blablabla");
return false;
}
return true;
}
}
And DB.class
#Stateless
public class DB {
#Inject
#RealClass
private EntityManager em;
public void persist(Object object) {
em.persist(object);
}
In the ProductController, there is really not much to test.. unless there is more logic that you did not post.
For testing the ProductModel, or any service-like class having the DB dependency i would suggest adding a project dependency to one of the mocking frameworks (i suggest Mockito as it is the most mature of them all).
For the addProducts method you could end up with following tests:
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
public class ProductModelTest{
#Mock
private DB dbMock;
#InjectMocks
private ProdcutModel = new ProductModel();
#Before
public void init(){
MockitoAnnotations.iniMocks(this);
}
#Test
public void shouldReturnTrue_whenEntityPersisted(){
doNothing().when(dbMock).persist(any(Product.class));
boolean result = productModel.addProduct(new Product());
assertTrue(result);
}
#Test
public void shouldReturnFalse_whenEntityPersisted(){
doThrow(RuntimeException.class).when(dbMock).persist(any(Product.class));
boolean result = productModel.addProduct(new Product());
assertFalse(result);
}
}
Regarding the DB-like repository classes.. i normally do not unit-test them. IF so i run integration tests on them.

JSF Interceptor doesn't fire

Why my interceptor doesn't work?
MyLog.java
#Inherited
#InterceptorBinding
#Retention(RUNTIME)
#Target({METHOD, TYPE})
public #interface MyLog {
}
MyLogger.java
#Interceptor
#MyLog
#Priority(Interceptor.Priority.APPLICATION)
public class MyLogger {
#AroundInvoke
public Object log(InvocationContext context) throws Exception{
System.out.println("begin " + context.getMethod().getName());
Object obj = context.proceed();
System.out.println("end " + context.getMethod().getName());
return obj;
}
}
PerguntaController.java
import interceptor.MyLog;
import java.io.Serializable;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
#Named("PerguntaController")
#SessionScoped
public class PerguntaController implements Serializable {
#EJB
private PerguntaFacade ejbFacade;
#MyLog
public List<> getAll() {
return ejbFacade.getAll();
}
#MyLog
public void update(Pergunta pergunta) {
ejbFacade.update(pergunta);
}
}
PerguntaFacade.java
import interceptor.MyLog;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class PerguntaFacade {
#PersistenceContext(unitName = "WebApplicationPU")
private EntityManager em;
#MyLog
public List<Pergunta> getAll() {
return em.createQuery("SELECT p FROM Pergunta p", Pergunta.class).getResultList();
}
#MyLog
public void update(Pergunta pergunta) {
//do something
}
}
When use getAll and update (from PerguntaController) in jsf page doesn't fire the interceptor neither getAll and update on PerguntaFacade. What im doing wrong?
Solved.
On beans.xml with bean-discovery-mode="annotated" doesn't work.
Then change to bean-discovery-mode="all" and works fine.

JSF - Getting NullPointerException in constructor when accessing getFacade()

this code produces NullPointerException. I don't know why. When I put the code from constructor to some other void with #PostConstruct - it works. I tried to initiate klientFacade - but it's not working, either. The class KlientFacade is #Stateless.
package view;
import entity.Klient;
import facade.KlientFacade;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import static util.Messages.addFlashMessage;
#ManagedBean
#ViewScoped
public class ManageClient implements Serializable {
#EJB
private KlientFacade klientFacade;
private List<Klient> clientList;
public List<Klient> returnClientList(){
return getKlientFacade().findAll();
}
public ManageClient() {
clientList = new ArrayList<>();
clientList = returnClientList();
}
public String removeClient(Klient klient){
addFlashMessage("Klient ["+klient.getLogin()+"] został usunięty.");
getKlientFacade().remove(klient);
return "manage";
}
public List<Klient> getClientList() {
return clientList;
}
public void setClientList(List<Klient> clientList) {
this.clientList = clientList;
}
public KlientFacade getKlientFacade() {
return klientFacade;
}
public void setKlientFacade(KlientFacade klientFacade) {
this.klientFacade = klientFacade;
}
}
Well its because injected objects are not instantiated before the constructor call. Thats why you are not getting NPE with #PostConstruct annotation. If you still need to access injected fields in constructor, try http://openejb.apache.org/constructor-injection.html.

i am getting nullpointer exception while using session ejb in my managed bean

my sessionfacade class
package com.entity;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class UsersFacade extends AbstractFacade<Users> implements UsersFacadeLocal
{
#PersistenceContext(unitName = "My_communityPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public UsersFacade() {
super(Users.class);
}
}
my managed bean class
package com.jsf;
import com.entity.Users;
import com.entity.UsersFacadeLocal;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.ManagedBean;
import javax.ejb.EJB;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
#Named(value = "loginMB")
#ManagedBean
#SessionScoped
public class LoginMB implements Serializable {
#EJB
private UsersFacadeLocal usersFacade;
protected Users user;
protected List<Users> lusers;
protected String username;
protected String password;
public LoginMB() {
lusers=usersFacade.findAll();
}
}
I dont know why my ejb injection in to mangedbean is not working. I am getting null pointer exception when i am calling findall(); method by using usersFacade
I am working on netbeans ide with glassfish server. i am just learning jpa in jsf please let me know where i am doing wrong
Container injects the EJB only after instantiating the managed bean. Use #PostConstruct annotation and use the EJB there. The annotated method will be called after the injection.

JSF 2.0 CDI - injected session bean within request bean contains null properties

I'm using JSF 2.0, CDI 1.0 within WebSphere App Server v8.0.0.5.
I have a bizarre situation... Upon successful login, a CDI session-scoped bean is created, and the user is redirected to a welcome page. The session-scoped bean is injected into a request-scoped bean referened on the welcome page. The problem is that the session-scoped bean ONLY retains its field values upon first successful login per browser. I've tried the same user using Chrome, Firefox, and even IE. If I log out or restart WAS and attempt to log in again, the session-scoped bean's values are all set to null when injected into the request-scoped bean.
I'm using javax.enterprise.context for all my scopes.
Please, I need emergency help. A lot is riding at stake due to this problem.
Relevant snippet of login form's Auth bean (I've omitted some code after the redirect):
import com.ibm.websphere.security.WSSecurityException;
import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.websphere.security.cred.WSCredential;
import com.ibm.websphere.wim.exception.WIMException;
import com.ibm.websphere.wim.util.SDOHelper;
import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.security.Principal;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.security.auth.Subject;
import javax.security.auth.login.CredentialExpiredException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import com.ibm.websphere.wim.SchemaConstants;
import com.ibm.websphere.wim.Service;
import com.ibm.websphere.wim.client.LocalServiceProvider;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import com.ibm.ws.security.core.ContextManagerFactory;
import commonj.sdo.DataObject;
#Named
#ConversationScoped
public class Auth implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6106803531512607236L;
private String userId;
private String password;
private String originalURL;
#Inject
UserService userService;
private Service service;
private String uniqueSecurityName;
private String l;
#PostConstruct
public void init() {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
System.out.println("The PostContstruct has been called.");
if (originalURL == null) {
originalURL = externalContext.getRequestContextPath() + "/index.xhtml";
} else {
String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);
if (originalQuery != null) {
originalURL += "?" + originalQuery;
}
}
}
public void login() throws IOException, WIMException, PrivilegedActionException {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
System.out.println("The login method has been called.");
try {
Principal userPrincipal = request.getUserPrincipal();
request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(userId, password);
User user = new User();
if (request.isUserInRole("STAFF")) {
Staff staff = userService.getStaff(userId);
user.setLocation(staff.getCenter().getCity());
user.setRole("STAFF");
user.setUserId(userId);
externalContext.getSessionMap().put("user", user);
externalContext.redirect("staff/staff-home?faces-redirect=true");
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "/index?faces-redirect=true";
}
The User bean:
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7198980241243868166L;
private String role;
private String location;
private String userId;
private Role sessionRole;
public User() { }
/**
* #return the role
*/
public String getRole() {
return role;
}
/**
* #param role the role to set
*/
public void setRole(String role) {
this.role = role;
}
/**
* #return the location
*/
public String getLocation() {
return location;
}
/**
* #param location the location to set
*/
public void setLocation(String location) {
this.location = location;
}
/**
* #return the userId
*/
public String getUserId() {
return userId;
}
/**
* #param userId the userId to set
*/
public void setUserId(String userId) {
this.userId = userId;
}
}
relevant portion of welcome page's bean:
import java.text.DateFormatSymbols;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#RequestScoped
public class CenterInfoBean {
#Inject
CenterInfo centerInfo;
#Inject
User user;
private State state;
private Center center;
#PostConstruct
public void init() {
center = centerInfo.getCenterByCityName(user.getLocation());
}
Why is auth only populated with values upon the initial login with a unique browser and never populated with values upon subsequent logins?
It is not a good idea to mix the container managed bean code with something like ,
User user = new User();
adding it in sessionMap should work but what if container has already resolved the injection of session bean in your request bean as you are already in session.
Try avoiding code like User user = new User(); when User is container managed.
In your case I would suggest checking if the User is already there in session.
User user = (User)externalContext.getSessionMap().get("user");
if so then update this reference , if it is not available then go with
User user = new User();

Resources