2012-07-09 30 views
0

我正在使用maven,jsf 2.0,java ee 6,jpa和glassfish。我有一个初始网页,询问您是否要登录或注册。如果他们说他们想登录,他们会被转发到facelets/primefaces 3,该facelets/primefaces 3会显示带有用户名和密码文本框的登录页面。对于用户名文本字段,它的值是facelets'target unreachable'

值= “#{} authenticator.username”

,我得到一个

“目标不可达,标识 '认证' 解决为空“

我正在使用beans.xml。我遵循了CDI bean的命名约定。 我在Authenticator构造函数中插入了一条日志消息,它看起来永远不会被调用,因为我没有收到消息。

另一个古怪的是,一旦在一个蓝色的月亮它的作品,我也得到类似如下:

07/08/2012 00:27:56.140信息...身份验证 - 在验证器构造

07/08/2012 00:27:56.171信息...验证器 - 让身份验证的用户名

07/08/2012 00:27:56.171信息...身份验证 - 在验证器构造

07/08/20 12 00:27:56.171信息...验证器 - 让身份验证密码

07/08/2012 00:27:56.171信息...身份验证 - 在验证器构造

07/08/2012 00:27 :56.171信息...验证器 - 让身份验证的用户名

07/08/2012 00:27:56.171信息...身份验证 - 在验证器构造

07/08/2012 00:27:56.171信息。 ..Authenticator - 获取Authenticator密码

07/08/2 012 00:28:05.843信息...身份验证 - 在验证器构造

07/08/2012 00:28:05.843信息...身份验证 - 在验证器构造

07/08/2012 00:28 :05.843 INFO ...身份验证 - 在验证器构造

07/08/2012 00:28:05.843信息...验证器 - 让身份验证的用户名

07/08/2012 00:28:05.843信息。 ..Authenticator - 身份验证器构造函数

07/08/2012 00:28:05.906信息...身份验证 - 在验证器构造

07/08/2012 00:28:05.906信息...验证器 - 让身份验证密码

07/08/2012 00:28: 26.000信息...身份验证 - 在验证器构造

07/08/2012 00:28:26.000信息...认证 - 在认证constructor`

07/08/2012 00:28:26.000信息...认证 - 中验证器构造

07/08/2012 00:28:26.031信息...认证 - 在验证器构造 07/08/2012 00:28:26.031信息...认证 - 获得身份验证密码

当它工作时,我不明白它为什么称之为构造这么多次。

这里进行管理(CDI)豆:

package com.mlb.mybills.view.user; 

import com.mlb.mybills.i18n.Messages; 
import java.util.Locale; 
import javax.faces.application.FacesMessage; 
import javax.faces.bean.ViewScoped; 
import javax.faces.context.ExternalContext; 
import javax.faces.context.FacesContext; 
import javax.inject.Named; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

@Named("authenticator") 
@ViewScoped 
public class Authenticator 
{ 
    private static final Logger log = LoggerFactory.getLogger(Authenticator.class); 

    private String username; 
    private char[] password; 

    public Authenticator() 
    { 
     log.info("in Authenticator constructor"); 
    } 

    public String getUsername() 
    { 
     log.info("getting Authenticator username"); 
     return username; 
    } 

    public void setUsername(String username) 
    { 
     log.info("getting Authenticator username"); 
     this.username = username; 
    } 

    public char[] getPassword() 
    { 
     log.info("getting Authenticator password"); 
     return password; 
    } 

    public void setPassword(char[] password) 
    { 
     log.info("setting Authenticator password"); 
     this.password = password; 
    } 

public void setPassword(String password) 
    { 
     log.info("setting Authenticator password"); 
     this.password = password.toCharArray(); 
    } 


    public String authenticate() 
    { 
     log.info("in Authenticator.authenticate"); 
     String result = null; 
     ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
     HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); 
     try 
     { 
      request.login(username, new String(password)); 
      //result = "/private/group.xhtml?faces-redirect=true"; 
     result = "/group.xhtml?faces-redirect=true"; 
     } 
     catch (ServletException ex) 
     { 
      log.error("Failed to authenticate user.", ex); 
      Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale(); 
     FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Messages.getString(
        "Login.InvalidIdPasswordMessage", locale), null); 
      FacesContext.getCurrentInstance().addMessage(null, facesMessage); 
     } 
     log.info("result=" + result); 
     return result; 
    } 

    public String logout() 
    { 
     ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
     HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); 
     try 
     { 
      request.logout(); 
     } 
     catch (ServletException servletEx) 
     { 
      log.warn("Failed to logout the user", servletEx); 
     } 
     return "/Login.xhtml?faces-redirect=true"; 
    } 
} 
+0

Post Authenticator托管bean代码。 – 2012-07-09 09:00:01

回答

1

你混合豆管理API。 @Named来自CDI,但@ViewScoped来自JSF。您需要使用这一个或另一个,而不是同时使用一个支持bean。现在这个bean基本上由CDI管理而没有任何有效的范围,因此每当解析EL表达式#{authenticator}时就构造bean。

要解决这个问题,如果你打算坚持到CDI,使用@ConversationScoped代替@ViewScoped

@Named 
@ConversationScoped 

或者,如果你打算坚持到JSF,使用@ManagedBean代替@Named

@ManagedBean 
@ViewScoped 

CDI方法的唯一缺点是您必须将@Inject a Conversation作为属性,然后自行开始和结束。

+0

+1 - 但能够开始/停止对话(通常对应于用例)绝对是一个功能,而不是一个缺点... – 2012-07-09 17:18:28

+0

@jan:我不是故意暗示它本身就是一个缺点,但只有在你打算模拟JSF视图范围的特定情况下;使用JSF注释可能更容易。 – BalusC 2012-07-09 17:24:06

+0

...那么你是对的:-) – 2012-07-09 17:28:30

1

由于您将CDI(@Named)和JSF(@ViewScoped)注释混合在一起,所以存在一些问题。由于这场比赛的缘故,这可能被称为很多次。您可以查看Seam Faces,MyFaces CODI或将您自己的ViewScoped版本转换为CDI,或者放弃CDI并直接转入JSF。

+0

它在我们的应用程序中使用Apache MyFaces CODI。 – 2012-07-09 22:14:29

+0

这是因为CODI和Seam 3都劫持JSF @ViewScoped注释并将其转换为CDI范围。 – LightGuard 2012-07-10 15:23:51

0

我找到了一个解决方案,虽然我不明白。我在以下链接中找到它:a link!而不是仅仅把@RequestScoped和@Named我还添加了faces-config.xml中

<managed-bean> 
    <managed-bean-name>authenticator</managed-bean-name> 
    <managed-bean-class>com.mlb.mybills.view.user.Authenticator</managed-bean-class> 
    <managed-bean-scope>session</managed-bean-scope> 
</managed-bean> 

以下项有了这个,我不再有目标不可达错误。

显然我还纠正了BalusC提到的上述错误。谢谢大家。

相关问题