JSF不会使用提交的输入值填充@Named @RequestScoped bean

Ema*_*arJ 3 jsf cdi jsf-2 managed-bean

这是我在这个美丽网站的第一个问题.我google了很多,但我没有找到任何解决方案.

我是JSF的新手,我正在通过Kent Ka lok Tong的"JSF 2 API和JBoss Seam"学习它.

现在我有一个简单的登录实现的问题.我有一个登录页面:

<?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://java.sun.com/jsf/html">
    <h:head>
        <title>Login</title>
    </h:head>
    <h:body>
        <h1>Login</h1>
        <h:messages for="loginForm" />
        <h:form id="loginForm">
            <h:inputText id="username" value="#{loginRequest.username}" required="true" />
            <h:inputSecret id="password" value="#{loginRequest.password}" required="true" />
            <h:commandButton value="Login" action="#{loginRequest.doLogin}"></h:commandButton>
        </h:form>

    </h:body>
</html>
Run Code Online (Sandbox Code Playgroud)

和一个支持bean:

package app.controller;

import app.model.beans.User;
import javax.faces.bean.RequestScoped;
import javax.inject.Named;


@Named("loginRequest")
@RequestScoped
public class LoginRequest {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public LoginRequest(){
    System.out.println("created " + this.toString());
    }

    public String doLogin(){

        if(this.username != null && this.password != null){

            if(this.username.equals("user") && this.password.equals("password")){
            //this.userHolder.setCurrentUser(username);
            return "success";

            }
        return "failure";

        }
        return "failure";

    }


}
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序时,我的用户名和密码属性结果为null.我调试了我的应用程序,我看到正确调用了setter方法.问题是,当调用setUsername时,会有LoginRequest的实例,当它被称为setPassword函数时,实例是不同的!似乎应用程序执行此操作:

obj1 = new LoginRequest() //username and password = null;
obj1.username = username;

obj1 = new LoginRequest() //username and password = null;
obj1.password = password;

obj1 = new LoginRequest() //username and password = null;
obj1.doLogin();
Run Code Online (Sandbox Code Playgroud)

我遇到麻烦的地方?哪里出错了?

非常感谢!

最好的祝福

马尔科

Bal*_*usC 16

从你的bean:

import javax.faces.bean.RequestScoped;
import javax.inject.Named;

@Named("loginRequest")
@RequestScoped
public class LoginRequest {
Run Code Online (Sandbox Code Playgroud)

您正在混合CDI和JSF注释.你可以而且不应该这样做.使用其中一个.我不知道这本书告诉你什么,但很可能你在导入@RequestScoped注释时选择了错误的自动完成建议.如果IDE建议您匹配任何书籍告诉您的任何内容,请注意.

所以,你应该用或者仅CDI注解

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

@Named("loginRequest")
@RequestScoped
public class LoginRequest {
Run Code Online (Sandbox Code Playgroud)

仅限JSF注释

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="loginRequest")
@RequestScoped
public class LoginRequest {
Run Code Online (Sandbox Code Playgroud)

否则,范围默认为,"none"并且引用bean的每个EL表达式都将创建一个全新且独立的bean实例.有三个EL表达式引用#{loginRequest}你最终将有3个实例.已设置名称的一个,其中一个设置了密码,另一个设置了操作.


具体问题无关,托管bean名称已默认为类名,第一个字符是小写符合Javabean规范.你可以完全省略这("loginRequest")部分.