0

I have a facelet component for displaying rss content:

rssFeedReader.xhtml

<h:outputText
    binding="#{rssReaderBean.text}"
    value="#{url}">
    <f:attribute
        name="url"
        value="#{url}" />
</h:outputText>

<ui:repeat
    value="#{rssReaderBean.rss}"
    var="rss">
    <ice:panelGroup>
        <ice:outputLabel
            value="#{rss['publishDate']} - "
            rendered="#{not empty rss['publishDate']}">
        </ice:outputLabel>
        <a
            href="#{rss['link']}"
            target="_blank">#{rss['title']}</a>
    </ice:panelGroup>
    <ice:panelGroup>
        <ice:outputLabel>#{rss['description']}</ice:outputLabel>
    </ice:panelGroup>
    <hr />
</ui:repeat>

and I include it where I need it like:

<myLib:rssFeedReader url="http://rss.news.yahoo.com/rss/topstories"></myLib:rssFeedReader >

If I include it with different urls, multiple times on my page, I do not understand why it displays multiple times the same FIRST url rss feed insted of taking each url separately.

To be able to read the specified url in my bean I bind it to the h:outputText from my facelet. Code from RssReaderBean bean:

private HtmlOutputText text;
public HtmlOutputText getText() {
    return text;
}

public void setText(final HtmlOutputText text) {
    this.text = text;
}

and the method which takes the url and returns the list:

public List<Rss> getRss() {
        try {
            final URL u = new URL((String) text.getAttributes().get("url"));
///read the rss feed and prepare the result, this code works good so its not required here
}

Can you see the problem...?

Thanks.

UPDATE: The bean has Request scope specified in faces-config.xml. If I print out the value of the text url it shows the LATEST url but all the content is taken from FIRST...

so basically for:

<gra:rssFeedReader url="http://blog.test.com/feed/rss/"></gra:rssFeedReader>
                    <gra:rssFeedReader url="http://rss.news.yahoo.com/rss/topstories"></gra:rssFeedReader>

it prints out the content of blog.test.com but text value when the page is rendered will show empty for first and yahoo url from second one...

Cristian Boariu
  • 9,603
  • 14
  • 91
  • 162

1 Answers1

2

The problem is caused because you're binding the <h:outputText> of the tag file to a single bean property. So, everytime you add another <myLib:rssFeedReader> tag, it will override the binding with the last added tag in the view. Finally, when #{rssReaderBean.rss} is been evaluated during rendering the view, it has only the last one at it hands.

There are several ways to solve this. The cleanest way is to create a fullworthy custom UIComponent wherein you specify the URL as an attribtue. The attribute is supposed to be specific to the component, not to a single bean property. An alternative is to use a Map<String, HtmlOutputText> property instead, this is however going to be clumsy.

Or if you're running a Servlet 3.0 / EL 2.2 capable container or replace the standard EL implementation by one which accepts method arguments, such as JBoss EL, then you could pass the URL as argument instead. E.g. #{rssReaderBean.rss(url)}. For installation/configuration detail, see this answer.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the answer...It's so ugly (but needed as you say) to create a full custom component just because you have a url dynamic param. In Seam this problem is solved easily because it can be passed as a parameter to the method and does not need any html text trick... – Cristian Boariu Apr 27 '11 at 15:07
  • @BalusC : If i make this a component can I just convert RssGravitantReaderBean to a component class which extens UIOutput or I still need to make a separate class for that and keep the bean for reading the rss feed? – Cristian Boariu Apr 27 '11 at 15:14
  • Truly you should be able to pass that as method argument in EL as well, but that requires replacement of EL implementation (I guess that you aren't on Servlet 3.0 yet). See answer update. – BalusC Apr 27 '11 at 15:19
  • @BalusC Yeah, I'm not on Servlet 3.0 yet.. So the solution with UIComponent remains... – Cristian Boariu Apr 27 '11 at 15:22
  • So replacing EL impl is not an option? – BalusC Apr 27 '11 at 15:27