CDI bean与托管bean的比较

时间:2019-02-13 13:16:59

标签: java jsf cdi managed-bean

我以前有Java SE的经验,所以我决定学习JSF。我正在使用JSF 2.2,Apache Netbeans 10,glassfish 5 / paraya 5.184。问题是,我在使用CDI bean和ManagedBeans

时遇到了一系列问题。

在完成在线教程之后,我能够基于WebFilter SessionScoped使用ManageBean和JSF登录页面来创建登录。

但是,我无法从其他JSF页面访问Bean属性(例如,登录的用户名),将Bean更改为CDI Bean(javax.inject.Named)解决了这个问题(因此,现在可以从其他页面),但创建了另一个页面。我偶尔会收到一个WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped错误,当登录控制器为javax.faces.bean.ManagedBean时不会出现。请注意,当调用WebFilter方法时,此错误是专门从doFilter生成的。

在开发过程中,我经常会得到WELD-000227: Bean identifier index inconsistency detected - the distributed container probably does not work with identical applications Expected hash: -XXXXXXXXX。虽然,我通常通过删除登录bean的implements Serializable位来解决此问题,然后进行部署,然后在重新部署之前将其重新添加(由于Netbean的自动部署功能,这很容易实现)

login.xhtml

    <h:body>
        <h:form>
            <h3>User Login</h3>
            <h:panelGrid columns="3"
                columnClasses="rightalign,leftalign,leftalign">

                <h:outputText value="Username" />
                <h:inputText id="username"
                             label="Username"
                             required="true"
                             value="#{login.user}" />
                <h:message for="username"/>

                <h:outputText value="Password" />
                <h:inputSecret id="password"
                               label="Password"
                               required="true"
                               value="#{login.pwd}" />
                <h:message for="password"/>

                <h:panelGroup/>
                <h:commandButton action="#{login.validateUsernamePassword}"
                    id="login" value="Login" />                
            </h:panelGrid>            
        </h:form>
    </h:body>

Login.java

@ManagedBean //This error occurs if I change it to @Named  --> WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
@SessionScoped
public class Login implements Serializable {
    private static final long serialVersionUID = 1897831825228386363L;

    private String pwd;
    private String msg;
    private String user;

    public String getPwd() {
            return pwd;
    }

    public void setPwd(String pwd) {
            this.pwd = pwd;
    }

    public String getMsg() {
            return msg;
    }

    public void setMsg(String msg) {
            this.msg = msg;
    }

    public String getUser() {
            return user;
    }

    public void setUser(String user) {
            this.user = user;
    }

    //validate login
    public String validateUsernamePassword() {
        boolean valid = LoginDAO.validate(user, pwd);
        if (valid) {
            HttpSession session = SessionUtils.getSession();
            session.setAttribute("username", user);
            try {
                FacesContext.getCurrentInstance().getExternalContext().redirect("explorer.xhtml");
            } catch (IOException ex) {
                Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
            }
            return "explorer";
        } else {
            FacesContext.getCurrentInstance()
                    .addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_WARN,
                                    "Incorrect Username and Passowrd",
                                    "Please enter correct username and Password"));
            return "login";
        }
    }

    //logout event, invalidate session
    public String logout() {
        HttpSession session = SessionUtils.getSession();
        session.invalidate();
        return "login";
    }
}

AuthorizationFilter.java

@WebFilter("/*")
public class AuthorizationFilter implements Filter {
    public AuthorizationFilter() {
    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest request, ServletResponse response,
                    FilterChain chain) throws IOException, ServletException {
        try {

            HttpServletRequest reqt = (HttpServletRequest) request;
            HttpServletResponse resp = (HttpServletResponse) response;
            HttpSession ses = reqt.getSession(false);

            String reqURI = reqt.getRequestURI();
            if (reqURI.indexOf("/login.xhtml") >= 0
                            || (ses != null && ses.getAttribute("username") != null)
                            || reqURI.indexOf("/public/") >= 0
                            || reqURI.contains("javax.faces.resource"))
                // this causes the WELD-001303 error
                chain.doFilter(request, response);
                //Logger.getLogger(this.getClass().getName()).log(Logger.Level.INFO, "doChain");
            else
            {
                resp.sendRedirect(reqt.getContextPath() + "/faces/login.xhtml");
            }                
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public void destroy() {

    }
}

admin.xhtml

<!--admin.xhtml-->
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <p>Welcome #{login.user}</p>
            <h:commandLink action="#{login.logout}" value="Logout"></h:commandLink>
        </h:form>
    </h:body>
</html>

这是我的问题:

  1. 当我将Login bean从Managed更改为CDI时,为什么WebFilter上确实会发生WELD-001303错误?

  2. 为什么在管理Bean时我无法从其他页面的Login Bean中访问username属性,而当我将其更改为CDI时,它可以按预期工作?

  3. 当我修改甚至不在Login.java文件中的源代码时,为什么登录bean会产生WELD-000227错误?

  4. 如何纠正这些错误?

我们将不胜感激任何帮助。

0 个答案:

没有答案