JSF MethodExpression 没有触发我的支持 bean 操作

标签 jsf methods uicomponents

我遇到的问题是我的代码没有触发我的支持 bean 中的操作。代码如下:

HtmlCommandButton replyCommentButton = new HtmlCommandButton();
replyCommentButton.setId("replyCommentButton" + commentCounter);
replyCommentButton.setValue("Create reply");
String action = "#{Handler.action_replyToComment}";
MethodExpression methodExpression =  
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
new Class<?>[0]);
replyCommentButton.setActionExpression(methodExpression);

在名为 RequestHandlerBean 的支持 bean(在 FacesConfig 中定义为 Handler)中,我有以下代码:

public void action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
}

有谁发现为什么当我点击按钮时没有任何反应?它没有正确触发事件。 html代码源码如下:

<input id="replyCommentButton1" type="submit" value="Create reply"   
name="replyCommentButton1"/>

正如我们所见,HTML 中没有定义任何操作。

编辑 2: 我刚刚在 Javadoc 中发现我的操作方法必须是公共(public)字符串。我现在已经在我的支持 bean 中更改了此设置,因此我的支持 bean 中的代码是:

public String action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
return null;
}

Edit2:我还确保将其封装在标签中,但仍然没有成功。元素上不应该有一个 action 属性吗?


Edit3:我的 bean 在我的 faces-config 中定义如下:

<managed-bean>
<description>
Handles the specific request.
</description>
<managed-bean-name>Handler</managed-bean-name>
<managed-bean-class>no.ngt.tech.rt2.beans.RequestHandlerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

此外,如果我选择像这样在 JSF 页面中输出:

<a4j:commandButton action="#{Handler.action_replyToComment}" value="Reply" /> 

效果很好

编辑 4 - 我的 JSP 页面 注意我现在也尝试使用已弃用的 setAction(methodBinding) ,但遗憾的是它也不起作用。

<%@ include file="_includes.jsp" %>
<f:view>
<html>
<head>
<title><h:outputText value="#{msgs.title}" /></title>
</head>
<body>
<br /><br /><br />



<%@ include file="_menu.jsp" %>

<rich:tabPanel switchType="client">

<rich:tab id="commentsTab" label="Comments" rendered="#{Handler.editRequest}">
<h:form>
         <ngt:commentTree binding="#{Handler.commentTree}" value="#{Handler.comments}"  />

         <br />

         <a4j:commandButton action="#{Handler.action_replyToComment}" value="testbutton" />
</h:form>    
</rich:tab>


</rich:tabPanel>

</body>
</html>
</f:view>

menu.jsp:

<h:form>
    <rich:toolBar itemSeparator="line" styleClass="toolbar" contentClass="toolbar" height="22">
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="Front" action="#{newRT.action_showFront}" />
        </rich:toolBarGroup>
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="New request" action="#{Step.action_showSteps}" />
        </rich:toolBarGroup>
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="Requests" action="#{Handler.action_showRequestsView}" />
        </rich:toolBarGroup>
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="Control-panel" action="#" />
        </rich:toolBarGroup>
        <rich:toolBarGroup location="right">
            <h:inputText styleClass="barsearch" value="#{Handler.search}" />
            <a4j:commandButton styleClass="barsearchbutton" action="#{Handler.action_GetRequestFromID}"  value="Search" />
        </rich:toolBarGroup>
    </rich:toolBar>
</h:form>


<br/><br/>

包括.jsp

<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="a4j" uri="http://richfaces.org/a4j" %>
<%@ taglib prefix="rich" uri="http://richfaces.org/rich"%>
<%@ taglib prefix="ngt" uri="http://MySpecialTagLib.no/"%>

编辑 7 - UIComponent 的 Java 代码:

这是 CommentsTreeUI.java:

public class CommentsTreeUI extends UIOutput {

    private static Logger logger = Logger.getLogger(CommentsTreeUI.class.getName());

    @Override
    public void encodeBegin(FacesContext context) throws IOException {

        List<CommentTag> value = (List<CommentTag>) getAttributes().get("value");
        int commentCounter = 0;

        if (value != null) {
            for (CommentTag comment : value) {
                commentCounter++;
                ResponseWriter commentContainerWriter = context.getResponseWriter();
                commentContainerWriter.startElement("div", this);
                commentContainerWriter.writeAttribute("id", "Comment" + commentCounter, null);

                String width = comment.getWidth();
                String height = comment.getHeight();

                String style = comment.getStyle();

                style = (style != null) ? style + ";" : "";

                if (width != null) {
                    style += "width:" + width + ";";
                }
                if (height != null) {
                    style += "height:" + height + ";";
                }

                commentContainerWriter.writeAttribute("style", style, null);

                String newComment = comment.getNewComment();
                if (newComment == null) {
                    newComment = "false";
                }

                String level = comment.getLevel();

                if (level != null) {
                    level = "commentContainerLevel" + level + newComment;
                }
                commentContainerWriter.writeAttribute("class", level, null);

                String title = comment.getTitle();
                if (title != null) {
                    commentContainerWriter.writeAttribute("title", title, null);
                }

                String titleText = comment.getTitleText();
                if (titleText != null) {
                    ResponseWriter titleTextWriter = context.getResponseWriter();
                    UIOutput titleTextComponent = new UIOutput();
                    titleTextWriter.startElement("div", titleTextComponent);
                    titleTextWriter.writeAttribute("class", "commentHeaderText" + newComment, null);
                    titleTextWriter.writeText(titleText + " | ", null);
                    titleTextWriter.startElement("a", titleTextComponent);
                    titleTextWriter.writeAttribute("onclick", "showCommentReply('CommentReply" + commentCounter + "')", null);
                    titleTextWriter.writeAttribute("class", "reply", null);
                    titleTextWriter.writeText("Reply", null);
                    titleTextWriter.endElement("a"); 
                    titleTextWriter.endElement("div");
                }

                String commentBody = comment.getCommentBody();
                if (commentBody != null) {
                    ResponseWriter commentBodyWriter = context.getResponseWriter();
                    UIOutput commentBodyComponent = new UIOutput();
                    commentBodyWriter.startElement("div", commentBodyComponent);
                    commentBodyWriter.writeText(commentBody, null);
                    commentBodyWriter.endElement("div");
                }

                ResponseWriter replyContainerWriter = context.getResponseWriter();
                UIOutput replyContainerComponent = new UIOutput();
                replyContainerWriter.startElement("div", replyContainerComponent);
                commentContainerWriter.writeAttribute("id", "CommentReply" + commentCounter, null);
                replyContainerWriter.writeAttribute("class", "replyContainer", null);

                ResponseWriter replyHeaderWriter = context.getResponseWriter();
                UIOutput replyHeaderComponent = new UIOutput();
                replyHeaderWriter.startElement("div", replyHeaderComponent);
                replyHeaderWriter.writeAttribute("class", "replyHeaderContainer", null);
                replyHeaderWriter.endElement("div");

                ResponseWriter replyFormWriter = context.getResponseWriter();
                UIInput replyFormComponent = new UIInput();
                replyFormWriter.startElement("fieldset", replyFormComponent);
                replyFormWriter.startElement("textarea", replyFormComponent);
                replyFormWriter.writeAttribute("type", "textarea", null);
                replyFormWriter.writeAttribute("rows", "5", null);
                replyFormWriter.writeAttribute("cols", "76", null);
                replyFormWriter.writeText("Write your answer here", null);
                replyFormWriter.endElement("textarea");


                //TODO: Fix so button has action to backing bean
                HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton();
                replyCommentButton.setId("replyCommentButton" + commentCounter);
                replyCommentButton.setValue("Create reply");
                String action = "#{RequestHandlerBean.action_replyToComment}";
                //replyCommentButton.setReRender("commentsTree");
                ExpressionFactory factory = context.getApplication().getExpressionFactory();
                Class [] argtypes=new Class[1];
                argtypes[0]=ActionEvent.class;

                MethodExpression replyActionExpression = factory.createMethodExpression(context.getELContext(), action, null, argtypes);
                replyCommentButton.setActionExpression(replyActionExpression);

                MethodExpression methodExpression = context.getCurrentInstance().getApplication().getExpressionFactory().
                        createMethodExpression(context.getCurrentInstance().getELContext(), action, null, new Class<?>[0]);
                replyCommentButton.setActionExpression(methodExpression);
                /*
                replyCommentButton.setAction(context.getApplication().createMethodBinding(action, argtypes));
                */

                replyCommentButton.encodeAll(context);
                //Todo above


                replyFormWriter.writeText(" ", null);
                replyFormWriter.startElement("input", replyFormComponent);
                replyFormWriter.writeAttribute("type", "button", null);
                replyFormWriter.writeAttribute("value", "Cancel ", null);
                replyFormWriter.writeAttribute("onclick", "hideCommentReply('CommentReply" + commentCounter + "')", title);
                replyFormWriter.endElement("input");
                replyFormWriter.endElement("fieldset");
                replyContainerWriter.endElement("div");
                commentContainerWriter.endElement("div");
            }
        } else { //value==null
            ResponseWriter writer = context.getResponseWriter();
            writer.startElement("div", this);

            writer.writeAttribute("id", getClientId(context), null);

            String width = (String) getAttributes().get("width");
            String height = (String) getAttributes().get("height");

            String style = (String) getAttributes().get("style");

            style = (style != null) ? style + ";" : "";

            if (width != null) {
                style += "width:" + width + ";";
            }
            if (height != null) {
                style += "height:" + height + ";";
            }

            writer.writeAttribute("style", style, null);

            String styleClass = (String) getAttributes().get("styleClass");
            if (styleClass != null) {
                writer.writeAttribute("class", styleClass, null);
            }

            String title = (String) getAttributes().get("title");
            if (title != null) {
                writer.writeAttribute("title", title, null);
            }

        }
    }

    @Override
    public void encodeEnd(FacesContext context) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.endElement("div");
    }

这是CommenstTreeTag:

public class CommentsTreeTag extends UIComponentTag {

    String style;
    String styleClass;
    String title;
    String width;
    String height;
    String value;
    Long parentId;

    public void release() {
        // the super class method should be called
        super.release();
        style = null;
        styleClass = null;
        title = null;
        height = null;
        width = null;
        parentId = null;
        value = null;
    }

    @Override
    protected void setProperties(UIComponent component) {
        // the super class method should be called
        super.setProperties(component);

        if (style != null) {
            component.getAttributes().put("style", style);
        }

        if (styleClass != null) {
            component.getAttributes().put("styleClass", styleClass);
        }

        if (width != null) {
            component.getAttributes().put("width", width);
        }

        if (height != null) {
            component.getAttributes().put("height", height);
        }

        if (title != null) {
            if (isValueReference(title)) {
                ValueBinding vb =
                        getFacesContext().getApplication().createValueBinding(title);
                component.setValueBinding("title", vb);
            } else {
                component.getAttributes().put("title", title);
            }
        }
        if (value != null) {
            if (isValueReference(value)) {
                ValueBinding vb =
                        getFacesContext().getApplication().createValueBinding(value);
                component.setValueBinding("value", vb);
                getFacesContext().getApplication().createValueBinding(value);

            } else {
                component.getAttributes().put("value", value);
            }
        }
        if (parentId != null) {
            component.getAttributes().put("parentId", parentId);
        }
    }



    public String getComponentType() {
        return "commentTree";
    }

    public String getRendererType() {
        // null means the component renders itself
        return null;
    }

    public String getHeight() {
        return height;
    }

    public void setHeight(String height) {
        this.height = height;
    }

    public String getWidth() {
        return width;
    }

    public void setWidth(String width) {
        this.width = width;
    }

    public String getStyle() {
        return style;
    }

    public void setStyle(String style) {
        this.style = style;
    }

    public String getStyleClass() {
        return styleClass;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

最佳答案

我认为您遇到的问题是由于您在 JSF 组件树中添加 commandButton 的方式造成的,或者更准确地说,是由于您没有将其添加到组件树中的方式造成的。

由于您没有将 commandButton 附加到 JSF 组件树,因此当呈现该组件时(通过调用 .encodeAll() 方法),它不会找到该组件嵌套的表单。 因此,HTML 输入未正确创建。

也许您可以尝试将创建的命令按钮直接添加到表单中,然后再要求呈现它。您可以使用以下代码来做到这一点:

// Search for the component HtmlForm that is a (in)direct parent of the current component
private UIComponent getCurrentForm(UIComponent currentComponent) {
    UIComponent parent = currentComponent.getParent();
    while ((parent != null) && !(parent instanceof HtmlForm)) {
        parent = parent.getParent();
    }
    return parent;
}


public void encodeBegin(FacesContext context) throws IOException {
    ...
    HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton();
    ...

    // Add the command button in the form that contains your custom component...
    UIComponent form = getCurrentForm(this);
    if (form != null) {
        form.getChildren().add(replyCommentButton);
    }
    replyCommentButton.encodeAll(context);
    ...
}

请注意,我已经测试了这段代码,所以也许您需要稍微修改一下...

如果它仍然不起作用,也许您需要检查代码以便在渲染类之外或encodeBegin之外创建commandButton...我认为修改JSF不是一个好主意渲染阶段的组件树...

关于JSF MethodExpression 没有触发我的支持 bean 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/665685/

相关文章:

java - 从链表中删除集合的方法

Python timedelta 收到意外结果

apache-flex - 未启用验证时清除 textInput 上的验证

java - 如何在没有 JFrame 的情况下创建自定义 float Swing 组件?

JSF 如何临时禁用验证器以保存草稿

java - 从单个 html 表单(jsf 页面)更新不同的 jpa 实体

jsf - 如何在 JSF1.2 的消息资源包中添加换行符(\n )

java - 在 AJAX 调用之间保留 JSF 消息

具有动态名称的 PHP 方法链接

用于显示图形(节点和边,二维)的 Android 组件?