JSF beans and object [duplicate] - jsf

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}

Related

Invalidating old httpsession drops current httpsession's context

My app handles logins with a #ViewScoped LoginBean, which is injected with a #SessionScoped SessionBean that stores user information and the current HttpSession. This app allows a user N separate sessions. After reaching that limit the user can only create another by killing off the oldest. This is done in the same LoginBean by asking the unmanaged UserSessionManager for the oldest SessionBean, and then invalidating its HttpSession.
Thus, logging in with session "A", we invalidate session "B". This all goes according to plan. But then, sometime during the remaining JSF phases, we also lose the SessionBean for session "A". Tracing down into the CDI code it appears that the session context for session "A" is being destroyed so when the redisplay finishes we have all new session beans.
We are using MyFaces 2.3.6, OpenWebBeans 2.0.16, OpenJDK 11
Is this a bug in OWB, or expected bahavior?
I'm also wondering if I have a fundamental misconception. If I save a SessionBean in my UserSessionManager and the retrieve it during a different session, should it retain its original state or does it get re-evaluated in the new SessionScoped context? I've been finding debugging difficult because my objects seem to actually be proxies, and the UI and debugger show different values at times.
Update 4/27/20:
The #SessionScoped SessionBean is being destroyed by org.apache.webbeans.web.context.WebContextsService#destroyRequestContext() where it destroys the "PropagatedSessionContext". This PropagatedSessionContext is being set by WebContextsService#destroySessionContext(), which is designating the local session to be destroyed despite being given a different specific session. This is where I'm wondering if it's a bug in OWB.
Here's a simplified example of the code:
(In this test code I've made the SessionManager an #ApplicationScoped bean. In the original code it isn't, but the behavior is the same.)
#Named("loginbean")
#ViewScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
#Inject private ExternalContext externalContext;
#Inject private SessionBean session;
#Inject private SessionManager sessionMgr;
public String killOldestDoLogin() {
List<SessionInfo> sessions = sessionMgr.getSessions();
SessionInfo oldest = sessions.get(0);
sessionMgr.killSession(oldest.getSessionId());
return doLogin();
}
public String doLogin() {
username = username.trim();
if (username != null && username.length() > 0) {
// After a successful login, avoid session fixation attacks by
// rotating the session ID. This isn't strictly necessary as Faces has
// its own session ID that a third party wouldn't have access to
if (externalContext != null) {
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
if (request != null && request.isRequestedSessionIdValid()) {
newSessionId = request.changeSessionId();
}
}
HttpSession http = (HttpSession)externalContext.getSession(false);
session.setUsername(username);
session.setHttpSession(http);
sessionMgr.addSession(http, session);
}
return "startPage.jsf");
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
.
#Named("sessionbean")
#SessionScoped
public class SessionBean implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private HttpSession httpSession;
public void reset() {
username = null;
httpSession = null;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public HttpSession getHttpSession() {
return httpSession;
}
public void setHttpSession(HttpSession session) {
this.httpSession = session;
}
public String getSessionId() {
return httpSession == null ? "null" : this.httpSession.getId();
}
}
.
#Named("sessionmanager")
#ApplicationScoped
public class SessionManager {
private HashMap<String,HttpSession> sessionMap = new HashMap<>();
private HashMap<String,SessionBean> beanMap = new HashMap<>();
public void addSession(HttpSession http, SessionBean bean) {
beanMap.put(http.getId(), bean);
sessionMap.put(http.getId(), http);
}
public boolean killSession(String sessionId) {
HttpSession session = sessionMap.get(sessionId);
sessionMap.remove(sessionId);
beanMap.remove(sessionId);
if (session != null) {
session.invalidate();
}
return session != null;
}
public List<SessionInfo> getSessions() {
List<SessionInfo> result = new ArrayList<>();
for (String sessionId : sessionMap.keySet()) {
SessionBean bean = beanMap.get(sessionId);
HttpSession http = sessionMap.get(sessionId);
SessionInfo info = new SessionInfo();
info.setUsername(bean.getUsername());
info.setSessionId(sessionId);
info.setHttpSession(http));
result.add(info);
}
return result;
}
}
.
public class SessionInfo {
private String username;
private String sessionId;
private HttpSession httpSession;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public HttpSession getHttpSession() {
return httpSession;
}
public void setHttpSession(HttpSession httpSession) {
this.httpSession = httpSession;
}
}

getUsername & phone is returning null datasnapshot

i was try to build real time car rent but i got this error returning null of datasnapshot and tried all fix thats impossible without any success
i don't know where is a problem and why my database dosn't response the request
DatabaseReference driverLocation = FirebaseDatabase.getInstance().getReference(Common.driver_location_tbl);
GeoFire gf = new GeoFire(driverLocation);
GeoQuery geoQuery = gf.queryAtLocation(new GeoLocation(mLastLocation.getLatitude(),mLastLocation.getLongitude()),distance);
geoQuery.removeAllListeners();
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(final String key, final GeoLocation location) {
FirebaseDatabase.getInstance().getReference(Common.driver_tbl)
.child(key)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Rider rider = dataSnapshot.getValue(Rider.class);
mMap.addMarker(new MarkerOptions()
.position(new LatLng(location.latitude,location.longitude))
.flat(true)
.title("Driver Name :"+rider.getUsername())
.snippet("Phone : "+rider.getPhone())
.icon(BitmapDescriptorFactory.fromResource(R.drawable.cars)));
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
and my Rider class
public class Rider {
private String email,password,phone,username;
public Rider() {
}
public Rider(String email, String password, String phone, String username) {
this.email = email;
this.password = password;
this.phone = phone;
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
How to fix app crach and returning null of datasnapshot ?
I have research for a fix and have not found anything.
ok i fixed it
problem was i register users with name not Uid so when i request name and phone got n

JSF EL Expressions and Java beans

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);
....

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}"/>

Resources