Question

Ok here is my session bean. I can always retrieve the currentUser from any Servlet or Filter. That's not the problem The problem is the fileList, and currentFile. I've tested with simple int's and Strings and its' the same effect. If I set a value from my view scoped bean I can get the data from another class.

@ManagedBean(name = "userSessionBean")
@SessionScoped
public class UserSessionBean implements Serializable, HttpSessionBindingListener {

    final Logger logger = LoggerFactory.getLogger(UserSessionBean.class);

    @Inject
    private User currentUser;

    @EJB
    UserService userService;

    private List<File> fileList;   

    private File currentFile;

    public UserSessionBean() {

        fileList = new ArrayList<File>();
        currentFile = new File("");
    }

    @PostConstruct
    public void onLoad() {

        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
        String email = principal.getName();

        if (email != null) {
            currentUser = userService.findUserbyEmail(email);
        } else {

            logger.error("Couldn't find user information from login!");
        }
    }

Here is an example.

My view scoped bean. This is how it is decorated.

 @ManagedBean
 @ViewScoped
 public class ViewLines implements Serializable {

    @Inject
    private UserSessionBean userSessionBean; 

Now the code.

    userSessionBean.setCurrentFile(file);
    System.out.println("UserSessionBean : " + userSessionBean.getCurrentFile().getName());

I can see the current file name perfectly. This is actually being printed from a jsf action method. So obviously the currentFile is being set.

Now if I do this.

@WebFilter(value = "/Download")
public class FileFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {        
        HttpSession session = ((HttpServletRequest) request).getSession(false);
        UserSessionBean userSessionBean = (UserSessionBean) session.getAttribute("userSessionBean");       

        System.out.println(userSessionBean.getCurrentUser().getUserId()); //works

        System.out.println("File filter" + userSessionBean.getCurrentFile().getName()); //doesn't work


        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

currentUser shows up fine but I can't see the file. It's just blank. The same thing happens with Strings, int's, etc.

Thanks for any help you can provide on this.

INFO: UserSessionBean : Line 3B--8531268875812004316.csv (value printed from view scoped bean)

INFO: File filter tester.csv (value printed when filter is ran.)

**EDIT**

This worked.

 FacesContext context = FacesContext.getCurrentInstance();
    userSessionBean = (UserSessionBean) context.getApplication().evaluateExpressionGet(context, "#{userSessionBean}", UserSessionBean.class);

I put this in the constructor of the ViewScoped and everything was fine. Now why isn't the inject doing what I thought? At first I thought maybe because I was using JSF managed beans instead of the new CDI beans. But I changed the beans to the new style(with named) and that was the same effect.

Does the inject only allow you to access the beans but not change their attributes?

Was it helpful?

Solution

You're mixing JSF and CDI. Your UserSessionBean is a JSF @ManagedBean, yet you're using CDI @Inject to inject it in another bean. CDI doesn't reuse the JSF managed one, it instead creates a brand new one. Use the one or the other, not both. The correct annotation to inject a JSF-managed bean is @ManagedProperty.

Replace

@Inject
private UserSessionBean userSessionBean; 

by

@ManagedProperty(value="#{userSessionBean}")
private UserSessionBean userSessionBean; 

and ensure that you don't have a import javax.enterprise.context anywhere in your code (which is the package of CDI annotations).

Alternatively, migrate all JSF bean management annotations to CDI bean management annotations.

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named
@SessionScoped
public class UserSessionBean implements Serializable {}

import javax.inject.Named;
import javax.faces.view.ViewScoped;

@Named
@ViewScoped
public class ViewLines implements Serializable {}

Additional advantage is that you can just @Inject it inside a regular servlet or filter without the need to manually grab it as request/session/application attribute.

Moreover, JSF bean management annotations are deprecated since JSF 2.3. See also Backing beans (@ManagedBean) or CDI Beans (@Named)?

OTHER TIPS

My best GUESS as to why this is happening, is because the variable file, is being set in view scope, and then passed by reference into the session scoped bean. Maybe this is happening because when the view scope bean is destroyed, it still has a reference to that variable, but doesn't bother to see if there's any other references to it in session scope, where it should be preserved. Hence, when it's destroyed, it's removed from both view and session scope in this case.

Could you try calling setCurrentFile with an object instantiated with 'new'? That might prove or disprove this hypothesis of mine.

Otherwise, my best advice would be to crack open the debugger, and see exactly where getCurrentFile is being changed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top