我在 WebSphere App Server v8.0.0.5 中使用 JSF 2.0、CDI 1.0。
我有一个奇怪的情况......成功登录后,会创建一个 CDI 会话范围的 bean,并将用户重定向到欢迎页面。会话范围的 bean 被注入到欢迎页面上引用的请求范围的 bean 中。问题是会话范围的 bean 仅在每个浏览器首次成功登录时保留其字段值。我已经尝试过使用 Chrome、Firefox 甚至 IE 的同一用户。如果我注销或重新启动 WAS 并尝试再次登录,则会话范围 bean 的值在注入请求范围 bean 时都设置为 null。
我对所有范围都使用 javax.enterprise.context。
拜托,我需要紧急帮助。由于这个问题,很多事情都处于危险之中。
登录表单的 Auth bean 的相关片段(我在重定向后省略了一些代码):
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";
}
用户 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;
}
}
欢迎页面 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());
}
为什么 auth 仅在使用唯一浏览器初始登录时填充值,而在后续登录时从未填充值?