JSF 2.0 CDI - injected session bean within request bean contains null properties

青春壹個敷衍的年華 提交于 2019-12-10 11:58:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!