JSF2 facelets and mvc - jsf

I'm trying to use mvc in my JSF2 facelets webapplication.
This is my logincontroller:
#ManagedBean
#ApplicationScoped
public class LoginControllerImpl implements LoginController{
#ManagedProperty(value = "#{applicationBean}")
private ApplicationBean applicationBean;
#Override
public boolean checkLogin(String username, String password) {
Store store = applicationBean.getStore(); //my model and my data are in this object
try {
store.checkLogin(username, password);
return true;
} catch (LoginException ex) {
return false;
}
}
}
This is my loginBean:
#ManagedBean
#SessionScoped
public class LoginBean implements Serializable{
#ManagedProperty(value="#{loginController}")
private LoginController loginController;
private String username;
private String password;
public void checkLogin(){
loginController.checkLogin(username, password);
}
}
Now I want to redirect the user to a welcome page when checklogin is true. Any ideas/tips how i should do that?

You can use implicit navigation, just return the page to which you want to access (relative to the current URL)
#ManagedBean
#SessionScoped
public class LoginBean implements Serializable{
#ManagedProperty(value="#{loginController}")
private LoginController loginController;
private String username;
private String password;
public String checkLogin(){
if (loginController.checkLogin(username, password)) {
return "welcome.xhtml";
}
return null; // won't change page
}
}

Related

Passing instance variable between managed beans

I am trying to get the UserBeans instance variables from LoginBean class. I want to use instance variable of Userbean into LoginBean class. Someone helps me.
Here, UserBean.java class :
#ManagedBean
#SessionScoped
public class UserBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And, Here's LoginBean.java class :
public class LoginBean {
public String login_check() {
if(name.equals("mahbub")){
return "success";
}else
return "fail";
}
Inject your UserBean class into LoginBean class and generate its getter and setter. So, your code should look like this.
public class LoginBean {
#ManagedProperty(value = "#{userBean}")
private UserBean userBean;
public String login_check() {
if(name.equals("mahbub")) {
return "success";
} else {
return "fail";
}
}
// userBean getter and setter here
}
Hope this would work for you. Cheers!
Use something like this
public class LoginBean {
#ManagedProperty(value = "#{userBean}")
private UserBean userBean;
public String login_check() {
if(userBean.getName().equals("mahbub")){
return "success";
}else
return "fail";
}
}
But you should rethink your design pattern

inject the same #SessionScoped Bean in different #Named Beans

I have a little javaee webproject and i need bean injection in it. i have a tomee server with cdi enabled. Here is a little test case.
Here is my #SessionScoped User object
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
#SessionScoped
public class User implements Serializable {
String userName;
public User () {}
public User (String userName) { this.userName = userName; }
public String getUserName() { return userName; }
public void setUserName(String userName) { this.userName = userName; }
}
and here are my two nearly identical beans:
#Named
#RequestScoped
public class BeanOne {
private String message;
#Inject User user;
#PostConstruct
public void init() { user = new User("TestName"); }
public String getMessage() { return user.getUserName(); }
}
In this bean i create a new user. the method getMessage returns the correct user name. I thought the user should still exist in the second bean because its #SessionScoped. Here is my second bean.
#Named
#RequestScoped
public class BeanTwo {
private String message;
#Inject User user;
public String getMessage() { return user.getUserName(); }
}
But in this bean the user.getUserName() returns null. How am i supposed to inject a #SessionScoped bean?
This happens because you have manually initialized user object in BeanOne init method. The purpose of dependency injection is to let some container create instances of objects for you, so you should never initialize objects manually. So just set a name for this user and it will be visible during session for all other beans.
#PostConstruct
public void init() { user.setUserName("TestName"); }

How to use CDI and Dependency Injection

I want to use the same object "User" within the Farma and the Pata objects. The object user is first initialized inside the Farma object. I tried to annotated with #inject, but the object user inside Pata, has the name with null value. Please, can anyone help me understand what I am doing wrong? Thank!
#Named
#SessionScoped
public class Farma implements Serializable {
#Inject private User user;
#PostConstruct
public void initialize(){
user.setName("MyName");
}
// Getters and Setters
}
#Named
#SessionScoped
public class Pata implements Serializable {
#Inject private User user;
public String getFuzzyName() {
// Here I want to use the object "user" with the name "MyName" to do some logic
}
// Getters and Setters
}
public class User implements Serializable {
private String name;
// Getters and Setters
Just scoping a User object won't allow you to initialize it.
Use "producer method" to control bean's creation.
Try this:
#SessionScoped
public class Pata implements Serializable {
#Inject
#SessionUser // inject here using the producer method
private User user;
public String getFuzzyName() {
return user.getName();
}
}
#SessionScoped
public class Farma implements Serializable {
#Produces
#SessionUser // qualifier to tie injection points to this method
#SessionScoped // to ensure it will be called once per session for any number of injection points
public User produceUser() {
System.out.println("Creating user");
User u = new User();
u.setName("User");
return u;
}
}
////// that's your custom qualifier, it's in a separate file
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({METHOD, FIELD, PARAMETER, TYPE})
public #interface SessionUser {}
// no scopes here, it is defined by the producer method
public class User implements Serializable {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
You need to understand scoping of CDI beans. The default scope, if none is specified, is the #Dependent scope, which means that an object exists to serve exactly one client (bean) and has the same lifecycle as that client (bean).
In this case it means that the user in Farma only exists for the Farma class and lives for the life of the Farma class.
The user in Pata is a different instance, and its lifecycle matches that of Pata.
You need to properly scope the User object.
As axiopisty said, adding #Named #SessionScoped is the correct way.
I tried and it works great.
#Named
#SessionScoped
public class Pata implements Serializable {
#Inject
private User user;
public String getFuzzyName() {
System.out.println(user.getName());
return user.getName();
}
public User getUser() {
return user;
}
public void setUser(final User user) {
this.user = user;
}
}
#Named
#SessionScoped
public class Farma implements Serializable {
#Inject
private User user;
#PostConstruct
public void initialize() {
user.setName("MyName");
}
// Getters and Setters
public User getUser() {
return user;
}
public void setUser(final User user) {
this.user = user;
}
}
#Named
#SessionScoped
public class User implements Serializable {
private String name = "Default";
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}
<h:outputText value="#{farma}"></h:outputText><br />
<h:outputText value="#{pata}"></h:outputText><br />
<h:outputText value="#{pata.fuzzyName}"></h:outputText>

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