JSF EL Expressions and Java beans - jsf

I have a JSF project and I am trying to create a login page, I have managed to get the username and password from the database and validate them, my project has a Java bean, managed bean and DAO classes, when the user successfully logs in, I would like to print Hello Mr.
< h:outputLabel value="#{mBLogin.user.firstName}" /> the Hello Mr. is printing but the name is not, although when testing my DAO class I'm printing the name to the console without any problem! Can someone advice what I am doing wrong?
My managed bean class:
#ManagedBean
#SessionScoped
public class MBLogin {
User user = new User();
LoginDAO loginDao = new LoginDAO();
public String validteStudent() {
boolean valid = loginDao.validateStudent(user.getUserId(), user.getPassword());
if (valid) {
user.getFirstName();
HttpSession session = SessionUtils.getSession();
session.setAttribute("username", user);
return "admin";
} else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,
"Incorrect Username and Passowrd", "Please enter correct username and Password"));
return "login";
}
}
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
}
My Java Bean class:
#Table(name = "students_info")
public class User {
#Column(name = "std_record_id")
private int id;
#Column(name = "std_id")
private String userId;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "web_password")
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My DAO class :
public class LoginDAO {
static JKPlainDataAccess dataAccess = JKDataSourceFactory.getPlainDataAccess();
User user;
public boolean validateStudent(String userName, String password) {
user = dataAccess.executeQueryAsSingleObject(User.class, "id,userId,firstName,lastName,password",
"SELECT std_record_id, std_id, first_name, family_name, web_password From students_info WHERE std_id=? and web_password=?",
userName, password);
JK.print("getAllEmployeeRecords() : ", user);
if(user != null) {
System.out.println(user.getFirstName());
System.out.println(user.getLastName());
return true;
}
return false;
}
public static void main(String[] args) {
LoginDAO a = new LoginDAO();
a.validateStudent("200663042001", "1234");
}
}
my xhtml page after the login page:
<ui:composition template="/WEB-INF/layouts/default.xhtml">
<ui:define name="content">
WELCOME Mr. <h:outputLabel value="#{mBLogin.user.firstName}" />
AND <h:outputLabel value="#{mBLogin.user.lastName}" />
</ui:define>
</ui:composition>

When validating, you seem to put the user as the session attribute without assigning it to the Managed Bean field:
session.setAttribute("username", user);
So either assign it also to the instance user variable or simply use:
<ui:composition template="/WEB-INF/layouts/default.xhtml">
<ui:define name="content">
WELCOME Mr. <h:outputLabel value="#{username.firstName}" />
AND <h:outputLabel value="#{username.lastName}" />
</ui:define>
</ui:composition>
Update
I would suggest changing your service method to:
public User validateStudent(..)
where you actually return the queried user instead of setting it in the DAO..
And thus you would change the ManagedBean method to:
public String validteStudent() {
User validatedUser = loginDao.validateStudent(user.getUserId(), user.getPassword());
if (validatedUser != null) {
this.user = validatedUser;
HttpSession session = SessionUtils.getSession();
session.setAttribute("username", user);
....

Related

JSF beans and object [duplicate]

This question already has an answer here:
How to send form input values and invoke a method in JSF bean
(1 answer)
Closed 5 years ago.
I have a JSF project, and I am trying to do a login page, in my project I have a managed bean that has a validate method for the username and password, and I have a bean class with setters and getters which has the user info that get filled for a database eg.(username, password, isActive, Full name), my question is how can I call the user info in JSF el expression in my xhtml pages if they are not in the managed bean?
Here is my java bean:
#Table(name="students_info")
public class User {
#Column(name="std_record_id")
private int id;
#Column(name="std_id")
private String userId;
#Column(name="first_name")
private String firstName;
#Column(name="web_password")
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
And here is my MBLogin:
#ManagedBean
#SessionScoped
public class MBLogin {
User user = new User();
LoginDAO loginDao = new LoginDAO();
public String validteStudent() {
boolean valid = loginDao.validateStudent(user.getUserId(), user.getUserId());
if (valid) {
HttpSession session = SessionUtils.getSession();
session.setAttribute("username", user);
return "student";
} else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,
"Incorrect Username and Passowrd", "Please enter correct username and Password"));
return "login";
}
}
}
Add a getter for the user:
#ManagedBean
#SessionScoped
public class MBLogin {
User user = new User();
LoginDAO loginDao = new LoginDAO();
public String validteStudent() {
boolean valid = loginDao.validateStudent(user.getUserId(), user.getUserId());
if (valid) {
HttpSession session = SessionUtils.getSession();
session.setAttribute("username", user);
return "student";
} else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,
"Incorrect Username and Passowrd", "Please enter correct username and Password"));
return "login";
}
}
public User getUser() {
return user;
}
}
Then in your xhtml you can call it like this:
#{user.id}, #{user.firstName}

JSF Datatable does not show all List fields(columns)

I want to display a table in JSF:DataTAble. I successfully retrived table from database to List of users type where "users" is my pojo class. Now I am having problem with displaying it on data table some of the columns like FName, LName, Pwd, displayed correctly but when i add other coulmns like "Note" "Email" it gives me this error
javax.servlet.ServletException: /dt.xhtml: Property 'Email' not found on type in.ali.pojo.users
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
root cause
javax.el.ELException: /dt.xhtml: Property 'Email' not found on type in.ali.pojo.users
com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)
com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:385)
com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:162)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:894)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
here is my xhtml page
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:dataTable value="#{pretechDataTableBean.user}" var="users">
<h:column>
<f:facet name="header">Name</f:facet>
#{users.FName}
</h:column>
<h:column>
<f:facet name="header">Email</f:facet>
#{users.Email}
</h:column>
<h:column>
<f:facet name="header">Password</f:facet>
#{users.pwd}
</h:column>
</h:dataTable>
</h:body>
</html>
here is my PretechDataTableBean which i used for retrieving data from DB
package com.pretech;
import in.ali.pojo.users;
import in.ali.util.HibernateUtil;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.util.ArrayList;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
/**
*
* #author vinod
*/
#ManagedBean
#RequestScoped
public class PretechDataTableBean {
public PretechDataTableBean() {
}
public List<users> getUser() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
List<users> users =null;
try
{
transaction = session.beginTransaction();
users = session.createQuery("from users").list();
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
session.close();
}
return users;
}
}
This is my users pojo
package in.ali.pojo;
// Generated Sep 28, 2013 3:55:01 PM by Hibernate Tools 4.0.0
/**
* users generated by hbm2java
*/
public class users implements java.io.Serializable {
private long UserId;
private String FName;
private String LName;
private long UserTypeId;
private String UserName;
private String Email;
private String Pwd;
private String Note;
private boolean IsActive;
public users() {
}
public users(long UserId) {
this.UserId = UserId;
}
public users(long UserId, String FName, String LName, long UserTypeId,
String UserName, String Email, String Pwd, String Note,
boolean IsActive) {
this.UserId = UserId;
this.FName = FName;
this.LName = LName;
this.UserTypeId = UserTypeId;
this.UserName = UserName;
this.Email = Email;
this.Pwd = Pwd;
this.Note = Note;
this.IsActive = IsActive;
}
public long getUserId() {
return this.UserId;
}
public void setUserId(long UserId) {
this.UserId = UserId;
}
public String getFName() {
return this.FName;
}
public void setFName(String FName) {
this.FName = FName;
}
public String getLName() {
return this.LName;
}
public void setLName(String LName) {
this.LName = LName;
}
public long getUserTypeId() {
return this.UserTypeId;
}
public void setUserTypeId(long UserTypeId) {
this.UserTypeId = UserTypeId;
}
public String getUserName() {
return this.UserName;
}
public void setUserName(String UserName) {
this.UserName = UserName;
}
public String getEmail() {
return this.Email;
}
public void setEmail(String Email) {
this.Email = Email;
}
public String getPwd() {
return this.Pwd;
}
public void setPwd(String Pwd) {
this.Pwd = Pwd;
}
public String getNote() {
return this.Note;
}
public void setNote(String Note) {
this.Note = Note;
}
public boolean isIsActive() {
return this.IsActive;
}
public void setIsActive(boolean IsActive) {
this.IsActive = IsActive;
}
}
The fields must be likeThis instead of LikeThis. Just change your JSF code to
<h:dataTable value="#{pretechDataTableBean.user}" var="user">
<h:column>
<f:facet name="header">Name</f:facet>
#{user.fName}
</h:column>
<h:column>
<f:facet name="header">Email</f:facet>
#{user.email}
</h:column>
<h:column>
<f:facet name="header">Password</f:facet>
#{user.pwd}
</h:column>
</h:dataTable>
And update the field names in your User class to follow the proper Java Bean naming convention.
public class users implements java.io.Serializable {
private long userId;
private String fName;
private String lName;
private long userTypeId;
private String userName;
private String email;
private String pwd;
private String note;
private boolean isActive;
//constructor, getters and setters
}
Apart from this, there are other bugs in your current design:
You must not have business logic in the getters of your managed bean, instead take advantage of the #PostConstruct method to initialize the necessary data to be used.
Since this bean looks that should stay alive while the user stays in the same view, it will be better to decorate it as #ViewScoped instead of #RequestScoped.
Use proper names for your classes and fields. For example, if you have a List<Something> field, name your variable somethingList or similar in order that the code is self-explanatory.
From these, you can change your managed bean to:
#ManagedBean
#ViewScoped
public class PretechDataTableBean {
private List<users> userList;
public PretechDataTableBean() {
}
#PostConstruct
public void init() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
List<users> users =null;
try
{
transaction = session.beginTransaction();
users = session.createQuery("from users").list();
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
session.close();
}
return users;
}
public List<users> getUserList() {
return this.user;
}
}
Since the field changed its name in the managed bean, you should edit it accordingly in the respective view:
<h:dataTable value="#{pretechDataTableBean.userList}" var="user">
Related info:
Why JSF calls getters multiple times
Communication in JSF 2: Managed bean scopes
JavaBeans API Specification , more specifically, Section 7: Properties.

Acces one managed bean from another by #ManagedProperty

I have 2 jsf pages and 2 beans for each.
First page is login page, where user types his login-password and then he is redirecting to his mailbox page. I want to get data from login page to mailbox page.
My bean for login page:
#ManagedBean(name = "login")
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
#RequestScoped
public class LoginFormBean {
#EJB
private LoginService loginService;
private String email;
private String password;
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public String login() {
if (loginService.loginUser(email, password))
return "mailBox.xhtml?faces-redirect=true";
else return "";
}
}
My bean for mailbox page:
#ManagedBean(name = "mailBox")
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
#RequestScoped
public class MailBoxFormBean {
#ManagedProperty(value = "#{login}")
private LoginFormBean login;
private String email = login.getEmail();
public void setLogin(LoginFormBean login) {
this.login = login;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
But when I'm redirecting to mailbox page, login bean is null and I can't get data from it.
What I'm doing wrong?
I've seen a lot of tutorials and answers (for example,
Using #ManagedProperty to call method between Managed beans or
http://www.techartifact.com/blogs/2013/01/access-one-managed-bean-from-another-in-jsf-2-0.html
)
I do exactly the same, but it isn't working for me.
The problem is that your login bean is marked as #RequestScoped, so as soon as you redirect away from the login page, the value is discarded. Try #SessionScoped instead: that's usually the correct scope for user login information.

JSF display username when the user login

How can I display the username from the userindex page once the user successfully login. Should I be pass it to the constructor and use it? or is there any better solution for this?
Create a session-scoped bean that stores either the user's ID (so you can lookup the user per request) or the actual user object itself.
#Named // or #ManagedBean
#SessionScoped
public class SessionGlobals {
private Integer userId;
public boolean isLoggedIn() {
return userId != null;
}
public Integer getUserId() {
return userId;
}
public void login(int userId) {
this.userId = userId;
}
public void logout() {
this.userId = null;
}
Inject this bean wherever it is required. When you login and logout, call the appropriate methods above.
For example:
#Named // or #ManagedBean
#RequestScoped
public class RequestGlobals {
public User getUser() {
return sessionGlobals.isLoggedIn()
? userDao.findById(sessionGlobals.getUserId())
: null;
}
#Inject
private UserDao userDao;
#Inject
private SessionGlobals sessionGlobals;
}
and in your page or template:
<h:outputText value="Welcome, #{requestGlobals.user.firstName}"
rendered="#{sessionGlobals.loggedIn}"/>

JSF Datatable can't get the value of OnetoMany relationship object?

I'm a JSF Newbie and having problem with displaying data using datatable. These is my scenario:
I want to display the contract(s) assigned to the Customer
JSF page's Datatable : customerdetail.jsp
<h:dataTable id="dt_contract_list" value="#{customerBean.customer.contracts}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="Contract Identifier"/>
</f:facet>
<h:outputText style="" value="#{item.contractIdentifier}"></h:outputText>
</h:column>
</h:dataTable>
Entity Bean : Customer.java
#Entity
#NamedQueries({
#NamedQuery(name="getCustomerByName", query="SELECT customer FROM Customer customer WHERE customer.name = :name"),
#NamedQuery(name="getAllCustomer", query="SELECT customer FROM Customer customer")
})
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
#OneToMany(targetEntity = Contract.class,
mappedBy = "customer",
cascade = CascadeType.ALL,
fetch=FetchType.EAGER)
private List<Contract> contracts = new ArrayList<Contract>();
public Customer() {
super();
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public List<Contract> getContracts() {
return this.contracts;
}
#Override
public boolean equals(Object object) {
if (this.getClass().isInstance(object)) {
return this.getName().equals(((Customer) object).getName());
} else {
return false;
}
}
}
BackingBean : CustomerBean.java
public class CustomerBean implements Serializable {
#EJB
private CustomerControllerLocal customerController;
private Customer customer;
public CustomerBean() {
customer = new Customer();
}
public String createCustomer() {
// create customer
}
public String updateCustomer() {
// update customer
}
public String deleteCustomer() {
// delete custoer
}
public String getCustomerByName() {
try {
customerController.getCustomerByName(customer.getName());
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "customer_got";
}
public String assignContractsToCustomer() {
// assign contract to customer
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
There's no errors and the whole business logic layer, data layer were tested and work fine but the result is null (and it shouldn't!) and no sign of any exception. Can anyone help me figure it out what's wrong with this? T___T
Your facelet code looks ok.
In your entity class there is one thing that looks suspicious. It is this line:
private List<Contract> contracts = new ArrayList<Contract>();
In the entity classe for my own projects (classes generated by netbeans) the relationship lists are never initialized. I am no expert in JPA but you could try it without the initialization part.

Resources