问题
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?
回答1:
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();
来源:https://stackoverflow.com/questions/15263390/jsf-2-0-cdi-injected-session-bean-within-request-bean-contains-null-properties