JSF最佳传递参数的方法

时间:2012-11-13 14:52:01

标签: jsf

我目前正在使用JSF,但由于我是一个老而又不高兴的php-dev,我总是搞砸了请求的GET-Parameters。 (在PHP中,您可以使用$_GET["paramname"]数组随时访问请求参数。

现在,我正在开发一个用户管理系统。 (CRUD)通常我会查看所有可用用户的列表,其中包含编辑/删除等选项。然后,编辑链接指向http:\\localhost\editUser.xhtml?userId=5

我还有一个名为UserEditController的控制器,它基本上保存用户实体并调用更新。

因此,在此Controller中,我使用@PostConstruct Annotation从DataService加载id为5的用户并将其存储在属性中。

问题在于:Wenn在APPLY_REQUEST_VALUES中进入PostConstruct-Method - 阶段我无法访问请求Faces Context的参数图(将为userId返回null)

控制器(简化):

@Named
@RequestScoped
UserEditController{


@Inject
private UserDataService userDataService;

private User currentUser;

@PostConstruct
public void initValues(){
    String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("userId");

    this.currentUser = userDataService.getUserById(id);
}

public String saveCurrentUser(){
    userDataService.updateUser(this.currentUser);
    return "userManagement"; //return to overview after saving
}

//getter and setter
}

这是有条件的。现在,所有表单字段都绑定到用​​户的属性,如#{userEditController.currentUser.forename}等。

我现在添加了一个带有操作属性{userEditController.saveCurrentUser()}

的保存按钮

然而,脚本然后进入APPLY_REQUEST_VALUES - 阶段并且再次调用UserEditController的initValues。

  • 这会在尝试访问RequestParameterMap
  • 时导致nullpointer异常
  • 显然我不想在保存之前重新加载用户: - )

这听起来像个愚蠢的问题,但我认为我在处理PHP-Style和JSF-Style之间搞乱了。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

将用户(或userID)传递给BackingBean的常用方法是使用以下选项之一:

http://www.mkyong.com/jsf2/4-ways-to-pass-parameter-from-jsf-page-to-backing-bean/

我认为主要问题是你的bean是@RequestScoped。如果按下编辑页面上的保存按钮,则发送新请求,因此将创建请求范围bean的新实例。只需将您的bean更改为@ViewScoped

更多信息:

答案 1 :(得分:0)

我尝试将其更改为ViewScoped,但每次访问属性时,最终都会以“调用构造函数”结束...

与此同时,我尝试了很多东西,没有按预期工作:

我可以让它工作的唯一情况是将控制器设置为“SessionScoped”。但我不认为这是一个好方法,因为我需要处理“清理”值并导致大量不需要(初始化)的bean ......

我创建了一个简单的项目来玩arround。下面是正在运行的会话范围版本。但是如果我改变范围,我需要在点击保存按钮时“重新加载”当前用户。如果没有访问请求参数,我就不知道如何实现。

(我尝试使用“表单”再次传递用户ID,但是我有问题“第一次传递id”)

继承我的样本。 (可以使用Getter和Setter,但没有提及它以保持简短)

用户级:

public class User {

   private String firstname;
   private String lastname;

   public User (String f, String l){
       this.firstname = f;
       this.lastname = l;
   }
}

DBSimulator:

@Named("dbSimulator")
@SessionScoped
public class DBSimulator implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 659826879566280911L;

private Map<String, User> data;

public DBSimulator() {
    //Load data
    User u1 = new User("Mickey", "Maus");
    User u2 = new User("Peter", "Pan");

    this.data = new HashMap<String, User>();
    this.data.put("Mickey", u2);
    this.data.put("Max", u1);
}

public List<User> getUserList(){
    List<User> l = new LinkedList<User>();

    for (Map.Entry<String, User> user : data.entrySet()) {
        l.add(user.getValue());
    }

    return l;

}

public void saveUser(User user){
    this.data.put(user.getFirstname(), user);
}
}

UserManagement-控制器:

@Named
@SessionScoped
public class UserManagementController implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = -4300851229329827994L;

@Inject
private DBSimulator dbSimulator;

private List<User> users;

public UserManagementController() {
    System.out.println("UserManagementController:construct()");
}

@PostConstruct
public void LoadUsers(){
    this.setUsers(this.dbSimulator.getUserList());
}
}

UserEdit控制器

@Named
@SessionScoped
public class UserEditController implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1867483972880755108L;

@Inject
private DBSimulator dbSimulator;

private User user;

public UserEditController() {
    System.out.println("UserEditController:construct()");
}

public String activateUser(User user){
    this.setUser(user);
    System.out.println("setting User");
    return "userEdit";
}

public String save(){
    //Save user
    this.dbSimulator.saveUser(user);
    return "userManagement";
}

}

最后两个XHTML文件: UserManagement.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">

<h:head>
<title>Test</title>
</h:head>
<h:body>
    <h:outputText value="Select user to edit." />

    <h:dataTable value="#{userManagementController.users}" var="user">
        <h:column>
            <f:facet name="header">Firstname</f:facet>
            <h:outputText value="#{user.firstname}" />
        </h:column>

        <h:column>
            <f:facet name="header">Lastname</f:facet>
            <h:outputText value="#{user.lastname}" />
        </h:column>

        <h:column>
            <f:facet name="header">Options</f:facet>
            <h:form>
                <h:commandLink action="userEdit" actionListener="#{userEditController.activateUser(user)}" value="edit user" />
            </h:form>
        </h:column>
    </h:dataTable>
</h:body>
</html>

UserEdit.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">


<h:head>
<title>Test</title>
</h:head>
<h:body>
    <h:form>
        <h:inputText value="#{userEditController.user.firstname}"></h:inputText>
        <br /><br />
        <h:inputText value="#{userEditController.user.lastname}"></h:inputText>
        <br /><br />
        <h:commandButton value="save" action="#{userEditController.save}"></h:commandButton>
    </h:form>

</h:body>
</html>

ps。:我不希望任何人“纠正”我的代码 - 但也许有完整的例子,有人可以看到,我的headeck来自:)

使用ViewScoped Beans会生成以下控制台输出:

[pageload]
12:07:49,126 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:07:49,334 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:07:49,341 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
[edit click]
12:08:35,410 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,411 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,412 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,413 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,414 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,414 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,415 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,416 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,416 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,417 INFO  [stdout] (http--0.0.0.0-8090-3) UserManagementController:construct()
12:08:35,476 INFO  [stdout] (http--0.0.0.0-8090-3) UserEditController:construct()
12:08:35,478 INFO  [stdout] (http--0.0.0.0-8090-3) setting User
12:08:35,494 INFO  [stdout] (http--0.0.0.0-8090-3) UserEditController:construct()
12:08:35,497 INFO  [stdout] (http--0.0.0.0-8090-3) UserEditController:construct()

显然用户不再设置,因为(ViewScoped)UserEditController在设置用户后已重建两次...