Jsf 2 h:commandButton在我将其包装成一个<;h:panelGroup渲染>;

Jsf 2 h:commandButton在我将其包装成一个<;h:panelGroup渲染>;,jsf-2,primefaces,facelets,jsf-2.2,commandbutton,Jsf 2,Primefaces,Facelets,Jsf 2.2,Commandbutton,这个主题之所以有“种类”是因为我在JSF2.2中有一个例子,我使用commandButton并调用bean函数两次(取决于url)。它基本上是相同的代码,只在一个示例中执行 下面是代码,代码下面有“错误”的描述: 用户bean @ManagedBean @RequestScoped public class User { private String name; private String surname; private int age; private int id; public S

这个主题之所以有“种类”是因为我在JSF2.2中有一个例子,我使用commandButton并调用bean函数两次(取决于url)。它基本上是相同的代码,只在一个示例中执行

下面是代码,代码下面有“错误”的描述:

用户bean

@ManagedBean
@RequestScoped
public class User {

private String name;
private String surname;
private int age;
private int id;

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

public String getSurname() {
    return surname;
}
public void setSurname(String surname) {
    this.surname = surname;
}

public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}

public User(String name, String surname, int age, int id) {
    super();
    this.name = name;
    this.surname = surname;
    this.age = age;
    this.id = id;
}

public User(){}

}
UsersBean:

@ManagedBean
@SessionScoped
public class UsersBean {

private List<User> listOfUsers = new ArrayList<User>();
private String passedParameter;

public UsersBean() {
    listOfUsers.add(new User("Tywin", "Lannister", 60, 1));
    listOfUsers.add(new User("Tyrion", "Lannister", 30, 2));
    listOfUsers.add(new User("Jaime", "Lannister", 31, 3));
    listOfUsers.add(new User("Cercei", "Lannister", 29, 4));
    listOfUsers.add(new User("John", "Snow", 31, 5));
}

public List<User> getAll() {

    System.out.println("getAall is called.");
    return listOfUsers;
}

public User getDetails() {
    passedParameter = (String) FacesContext.getCurrentInstance()
            .getExternalContext().getRequestParameterMap().get("userID");
    int id = Integer.parseInt(passedParameter);
    User selected = null;
    for (User u : listOfUsers) {
        if (u.getId() == id) {
            selected = u;
        }
    }
    return selected;
}

public String addUser(User u) {
    System.out.println("addUser is called.");
    if (u.getId() != 0) {
        for (User edit : listOfUsers) {
            if (edit.getId() == u.getId()) {
                System.out.println("Found it!");
                edit.setAge(u.getAge());
                edit.setName(u.getName());
                edit.setSurname(u.getSurname());
            }
        }

    } else {
        u.setId(listOfUsers.size() + 1);
        listOfUsers.add(u);
    }

    return "";
}
}
@ManagedBean
@会议范围
公共类UsersBean{
private List listOfUsers=new ArrayList();
私有字符串passedParameter;
公共用户bean(){
添加(新用户(“Tywin”,“Lannister”,60,1));
添加(新用户(“Tyrion”,“Lannister”,30,2));
添加(新用户(“Jaime”,“Lannister”,31,3));
添加(新用户(“Cercei”,“Lannister”,29,4));
添加(新用户(“John”,“Snow”,31,5));
}
公共列表getAll(){
System.out.println(“调用getAall”);
返回用户列表;
}
公共用户getDetails(){
passedParameter=(字符串)FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap().get(“用户ID”);
int id=Integer.parseInt(passedParameter);
用户选择=空;
用于(用户u:ListoUsers){
if(u.getId()==id){
所选=u;
}
}
返回选中的;
}
公共字符串addUser(用户u){
System.out.println(“调用addUser”);
如果(u.getId()!=0){
对于(用户编辑:ListoUsers){
if(edit.getId()==u.getId()){
System.out.println(“找到了!”);
edit.setAge(u.getAge());
edit.setName(u.getName());
edit.setSurname(u.getNames());
}
}
}否则{
u、 setId(listOfUsers.size()+1);
添加(u);
}
返回“”;
}
}
users.xhtml:

    <f:view>
        <!-- http://stackoverflow.com/questions/8083469/method-must-have-signature-string-method-etc-but-has-signature-void -->
        <h:dataTable value="#{usersBean.all}" var="u">

            <h:column>
                <f:facet name="header">
                    User ID
                </f:facet>
                    #{u.id}
            </h:column>

            <h:column>
                <f:facet name="header">
                    Name
                </f:facet>
                    #{u.name}
            </h:column> 

            <h:column>
                <f:facet name="header">
                    Details
                </f:facet>

                <h:link outcome="users" value="edit user">
                    <f:param name="userID" value="#{u.id}"></f:param>
                    <f:param name="action" value="edit"></f:param>
                </h:link>

                &nbsp;

                <h:link outcome="usersDetails" value="get details">
                    <f:param name="userID" value="#{u.id}"></f:param>
                </h:link>                   
            </h:column> 

        </h:dataTable>

        <h:panelGroup rendered="#{param['action'] == 'edit'}">
            <h1>Edit!</h1>
            <h:form>
                <ui:param name="editUser" value="#{usersBean.details}"></ui:param>
                <h:outputText value="Name"></h:outputText>
                <h:inputText value="#{editUser.name}"></h:inputText> <br />

                <h:outputText value="Surname"></h:outputText>
                <h:inputText value="#{editUser.surname}"></h:inputText> <br />

                <h:outputText value="Age"></h:outputText>
                <h:inputText value="#{editUser.age}"></h:inputText> <br />

                <h:commandButton action="#{usersBean.addUser(editUser)}" value="Edit" type="submit">    </h:commandButton>
            </h:form>
    </h:panelGroup>

        <h:panelGroup rendered="#{empty param['action']}">
            <h1>Add!</h1>
            <h:form>
                <h:outputText value="Name"></h:outputText>
                <h:inputText value="#{user.name}"></h:inputText>
                <h:outputText value="Surname"></h:outputText>
                <h:inputText value="#{user.surname}"></h:inputText>
                <h:outputText value="Age"></h:outputText>
                <h:inputText value="#{user.age}"></h:inputText>
                <h:commandButton action="#{usersBean.addUser(user)}" value="Add" type="submit"></h:commandButton>
            </h:form>
        </h:panelGroup>     

    </f:view>

用户ID
#{u.id}
名称
#{u.name}
细节
编辑



添加
好吧,一切都很顺利。usersBean.addUser添加用户。如果我为ID添加另一个inputText,并输入一个现有ID,则相应的函数会更新这些值。所以,addUser函数按预期工作

问题在于,如果发生

<h:panelGroup rendered="#{param['action'] == 'edit'}">

正如您在上面的xhtml中所看到的,代码基本相同,唯一的例外是我填写了所选用户的数据。这是可行的,我将适当的数据输入到输入字段中,但当我更改它们并单击“编辑”时,什么也没有发生。函数没有被调用!而在add的情况下,调用函数并使其工作。 在编辑时似乎没有定义任何操作,它只重新加载页面(提交),而没有实际操作addUser

这是如何造成的,我该如何解决它?

这是因为
{param['action']='edit'}
在处理表单提交时没有计算
true
,因此
在处理表单提交时基本上没有呈现,包括
。表单submit没有将该参数传递回JSF。这样,JSF将看不到
,因此永远无法对其操作事件进行解码和排队。您需要确保所有的
呈现的
条件在处理表单提交期间的评估结果与在显示表单期间的评估结果相同(这是JSF防止篡改/黑客请求的一部分,否则最终用户将能够执行未呈现的命令按钮,如仅管理员按钮)

因此,您基本上需要在回发期间保留该参数,以便
呈现的
表达式在处理表单提交期间仍然计算
true
。这可以通过几种方式实现:

  • 将其添加为相关的
    中的

    <h:commandButton action="#{usersBean.addUser(editUser)}" value="Edit" type="submit">
        <f:param name="action" value="#{param.action}" />
    </h:commandButton>
    
  • 如果您已经在使用JSF实用程序库,请使用它的
    而不是
    ,这使您能够提交到当前请求URI而不是当前JSF视图ID。这样,GET请求字符串将自动保留,并且您不需要在所有命令按钮上复制粘贴
    ,如#1:

    
    ...
    
  • 另见:
    • -第6点
    <f:metadata>
        <f:viewParam name="action" value="#{usersBean.action}" />
    </f:metadata>
    ...
    <h:panelGroup rendered="#{usersBean.action}">
        ...
    </h:panelGroup>
    
    <o:form useRequestURI="true">
        ...
    </o:form>