【问题标题】:facelet dataTable: method not found in backing bean, trying to send instance back to beanfacelet dataTable:在支持 bean 中找不到方法,试图将实例发送回 bean
【发布时间】:2012-04-06 01:55:49
【问题描述】:

如何将特定行的 ListDataTable 所在的当前 javax.mail.Message 发送回支持 bean,以便获取该特定 Message 实例的一些标头信息?我认为问题在于这是来自客户端数据表中的。

如何使 getUrl 可用于 ListDataTable?

我试过了:

<h:outputText value="#{messageBean.foo(m.header("Archived-at"))}"></h:outputText>

返回错误:

Element type "h:outputText" must be followed by either attribute specifications, ">" or "/>".

我认为它类似于command link,它建议的语法为:

<h:commandLink action="#{bean.insert(item.id)}" value="insert" />

这与我正在做的事情很接近。就我而言,我只想将特定消息发送回 MessageBean.getUrl(Message) 但这并没有像我预期的那样工作。

我也试过了:

/foo/client.xhtml @48,61 value="#{messageBean.url(m)}": Method url not found

所以这显然不是将对象从模板客户端发送到支持 bean 的正确方法。但是,这就是我想要的方法,将实际的 Message 实例发送回 bean。

facelets 2.0 客户端:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./template.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:f="http://java.sun.com/jsf/core">
    <ui:define name="content">
        <h:dataTable value="#{messageBean.model}" var="m">
            <h:column>
                <f:facet name="subject">
                    <h:outputText value="subject" />
                </f:facet>
                <h:outputText value="#{m.subject}"></h:outputText>
            </h:column>
            <h:column>
                <f:facet name="content">
                    <h:outputText value="content" />
                </f:facet>
                <h:outputText value="#{m.sentDate}"></h:outputText>
            </h:column>
            <h:column>
                <f:facet name="date">
                    <h:outputText value="date" />
                </f:facet>
                <h:outputText value="#{m.sentDate}"></h:outputText>
            </h:column>
        </h:dataTable>
    </ui:define>
</ui:composition>

支持 bean:

package net.bounceme.dur.nntp;

import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.inject.Named;
import javax.mail.Header;
import javax.mail.Message;

@Named
@SessionScoped
public class MessageBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger logger = Logger.getLogger(MessageBean.class.getName());
    private static Level level = Level.INFO;

    public MessageBean() {
        logger.log(level, "MessageBean..");
    }

    public DataModel getModel() throws Exception {
        logger.log(level, "MessageBean.getModel..");
        List<Message> messages = new ArrayList<Message>();
        SingletonNNTP nntp = SingletonNNTP.INSTANCE;
        messages = nntp.getMessages();
        DataModel messagesDataModel = new ListDataModel(messages);
        return messagesDataModel;
    }

    public List<String> getStringHeaders(Message message) throws Exception {
        List<Header> headerListOfHeaders = getHeaders(message);
        List<String> stringListOfHeaders = new ArrayList<String>();
        for (Header h : headerListOfHeaders) {
            stringListOfHeaders.add(h.getName() + " " + h.getValue() + "\n");
        }
        return stringListOfHeaders;
    }

    public URL getUrl(Message message) throws Exception {
        List<Header> headers = getHeaders(message);
        URL url = new URL("http://www.google.com/");
        for (Header h : headers) {
            if ("Archived-at".equals(h.getName())) {
                String s = h.getValue();
                s = s.substring(1, s.length() - 1);
                url = new URL(s);
            }
        }
        return url;
    }

    private List<Header> getHeaders(Message message) throws Exception {
            Enumeration allHeaders = message.getAllHeaders();
            List<Header> headers = new ArrayList<Header>();
            while (allHeaders.hasMoreElements()) {
                Header hdr = (Header) allHeaders.nextElement();
                headers.add(hdr);
            }
            return headers;
        }
}

我想将 getUrl 保留在 MessageBean 中,但愿意将该方法拆分到另一个类中。但是,哪个类,以及如何引用它?只是像 MyBeanOps 之类的?

【问题讨论】:

  • 您没有使用 JSP 或 Servlet。您正在将 JSF 与 Facelets 一起使用。请不要在问题上贴错标签。

标签: java jsf facelets el


【解决方案1】:

关于你的第一次尝试,

<h:outputText value="#{messageBean.foo(m.header("Archived-at"))}" />

这会失败,因为您过早结束属性值,然后以无效的属性 name=value 语法开始。注意语法高亮。对嵌套字符串使用单引号而不是双引号:

<h:outputText value="#{messageBean.foo(m.header('Archived-at'))}" />

关于你的第二次尝试,

<h:commandLink action="#{bean.insert(item.id)}" value="insert" />

我不确定为什么这对你来说会失败,因为它似乎是合法的语法。

至于您没有显示任何代码而只显示错误消息的第三次尝试,

/foo/client.xhtml @48,61 value="#{messageBean.url(m)}": Method url not found

那是因为你没有方法url(Message message)。相反,您有一个方法getUrl(Message message)。所以你应该使用

<h:commandLink action="#{messageBean.getUrl(m)}" value="insert" />

但是,这并不能解决问题。这不是一个有效的操作方法。这应该被视为一个值表达式。所以,应该这样做:

<a href="#{messageBean.getUrl(m)}">insert</a>

这会将URL#toString() 的结果打印为href 属性的值,这正是您想要的。当然,您也可以为此使用&lt;h:outputLink&gt;

<h:outputLink value="#{messageBean.getUrl(m)}">insert</h:outputLink>

【讨论】:

  • 好的,我还在看你的回答,谢谢。我还找到了stackoverflow.com/questions/3951263/…,所以我会在这里和其他问题上尝试你的建议。标签已修复。
  • 该答案针对没有可用 EL 2.2 的旧环境。但是,您的支持 EL 2.2。这样你就可以得到更简单的代码。更完整的概述可以在stackoverflow.com/questions/4994458/… 中找到。请注意,这不适合满足您仅打印 URL 的特定功能要求。从上到下阅读答案:)
  • insert 很好。为什么是 messageBean.getUrl(m) 而不是 messageBean.url(m)?那是因为它是一个动作,所以 bean 没有“url”属性吗?再次感谢。我可以使用实际的链接文本代替“插入”吗? etc... ?
  • '#{messageBean.getUrl(m)}' 再次感谢。
  • 因为您使用() 调用方法,而不是访问隐式前缀get 和后缀() 的属性。
猜你喜欢
  • 2012-06-03
  • 2014-12-11
  • 1970-01-01
  • 2016-07-07
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 2014-02-16
相关资源
最近更新 更多