簡體   English   中英

許多@RequestScoped子類從@SessionScoped bean訪問變量而沒有復制粘貼@ManagedProperty?

[英]Many @RequestScoped subclasses access variable from @SessionScoped bean without copy-pasting @ManagedProperty?

我閱讀了BalusC 關於JSF通信的出色教程 ,它幫助我建立了應用程序的基礎。 我想與所有子類共享在SessionScoped BaseBean類中設置的當前登錄的User對象。 是否可以為每個需要引用登錄用戶的單個后備bean不注入BaseBean作為@ManagedProperty來完成此操作?

我的課程在下面列出。 請讓我知道是否需要更多信息,我很樂意更新我的問題。

BaseBean類

所有其他bean是此bean的子類。 我這樣做是為了在bean之間重用代碼。

@ManagedBean
@SessionScoped
public class BaseBean {

    @EJB
    protected UserDao userDao;
    // Other DAOs along with methods (like isLoggedIn()) shared between beans

    private User loggedInUser;

    public User getLoggedInUser() {
        return loggedInUser;
    }

    public void setLoggedInUser(User user) {
        loggedInUser = user;
    }

    public boolean isLoggedIn() {
        return loggedInUser != null;
    }

}

LoginBean類

登錄頁面的后備bean。 為了減少數據庫調用的次數,我使用了上一教程中的@ManagedProperty方法在@SessionScoped BaseBean中設置User對象。 現在登錄並設置loggedInUser可以正常工作。

@ManagedBean
@RequestScoped
public class LoginBean extends BaseBean {

    @ManagedProperty(value = "#{baseBean}")
    protected BaseBean baseBean;

    private String username;
    private String password;

    public String login() {
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.login(username, password);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            baseBean.setLoggedInUser(userDao.getUser(username));
        }
        return "index";
    }

    public String getUserFirstName() {
        return baseBean.getLoggedInUser().getFirstName();
    }

    // Getters and Setters, including for the @ManagedProperty baseBean.

}

CreateReport類

這是很多人支持的一個例子。 我想引用當前登錄的用戶以創建報告,但是,如果運行以下代碼,則User為null 我可以使它正常工作的唯一方法是添加一個@ManagedProperty條目,該條目具有BaseBean的getter和setters,就像LoginBean類中那樣。 我真的想避免這種情況,因為我會將這段代碼復制粘貼到幾乎所有我擁有的每個后備bean中!

@ManagedBean
@RequestScoped
public class CreateReport extends BaseBean {

    private Report report = new Report();

    public String createReport() {
        report.setOwner(getLoggedInUser()); // Use inherited method
                                            // instead of DI-ing BaseBean
        reportDao.create(report);
        return "index";
    }

}

二手軟件

  • 玻璃魚4
  • Mojarra 2.2

編輯

我發現的一個解決方案是直接從FacesContext獲取BaseBean的實例(我想其他豆不在同一上下文中或“看不到?”)。 以下代碼(來自BaseBean)可以滿足我的要求,但是任何bean子類都必須調用base() ,這似乎很尷尬和錯誤。

protected FacesContext context = FacesContext.getCurrentInstance();

public BaseBean base() {
    return (BaseBean) context.getApplication().evaluateExpressionGet(context, "#{baseBean}", BaseBean.class);
}

使BaseBean本身成為托管Bean,並將其用作所有其他托管Bean的超類是不應該發生的兩件事。

相反,您可以:

  • BaseBean刪除@ManagedBean批注。
  • 保存loggedInUser到會話。
  • isLoggedIn保留為BaseBean的受保護方法。 您將能夠通過FacesContext到達會話,並從會話獲取loggedInUser

    ((HttpServletRequest)FacesContext.getCurrentInstance() .getExternalContext().getRequest()).getSession()

ps:提供靜態變量時,我不知道我在想什么。

我可以看到您要實現身份驗證和身份驗證控件,然后可以使用JSF過濾器。 您可以將BaseBean類保留在會話范圍內,創建一個實現javax.servlet.Filter的新類,並在此類中通過會話獲取BaseBean類,例如:

public class LoginFilter implements javax.servlet.Filter {

    @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {    
    HttpServletRequest req = (HttpServletRequest) request;
    BaseBean base = (BaseBean) req.getSession().getAttribute("baseBean");

    if (base != null && base.isLoggedIn()) {
        // to do something
        chain.doFilter(request, response);
    } else {
        // to do something
        HttpServletResponse res = (HttpServletResponse) response;
        res.sendRedirect(req.getContextPath() + "/index.xhtml");
    }
}

public void init(FilterConfig config) throws ServletException {
    // to do something
}

public void destroy() {
    // to do something
}   

}

現在,如果要使用BaseBean類創建報告,則可以獲取Session的BaseBean類:

BaseBean base = (BaseBean) ( FacesContext.getCurrentInstance()
    .getExternalContext().getRequest()).getSession().getAttribute("baseBean") );

然后,在您的情況下,我的建議是避免繼承,並使用JSF的優點。

希望這些信息對您有所幫助。

祝好運。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM