views:

42

answers:

2
+1  Q: 

JSF Limitations

I'm currently just exploring JSF 2 in the JEE 6 stack.

I find quite a bit of limitations with JSF and the way ManagedBeans are used is very counter-intuitive / odd:

It seems that, in order to execute an action event, you have to use <h:commandLink> tag. Thats all well if I was for example, posting form data. However in this case, all I wanted to do was to simply view a book using the url e.g.: viewBook?id=2. If i was using spring, it would have been easy:

@Controller
public class BookController {

  @RequestMapping("/viewBook")
  public String viewBook(@RequestParam("id") Long id, Model model) {
       // all the method params(id, model) are provided by spring
       BookDTO book = bookService.load(id);
       model.addAttribute("book", book);
       return "BookView";
  }

}

However using JSF, I have to:

<h:form>
  <h:commandLink value="#{bookController.viewBook}">
    <f:param name="id" value="#{book.id}"/>
  </h:commandLink>
</h:form>

and the backing bean:

@ManagedBean
public class BookController {

  private BookDTO book;

  public String viewBook() {

    Long id = Long.parseLong(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValueMap().get("id"));

    book = bookService.load(id);

    return "BookView";

  }
  // ...
}

Question is: Is there a framework for JSF2 that provides what spring MVC does?

Another question is: What does JSF provide that couldn't easily be achieved using Spring ?

In my view, the whole JSF / Facelet etc technology is overly complex, over-engineered and counter-intuitive. I hold the same view on EJBs btw.

These views are formed after having explored JEE6, by writing a small JEE web application.

Thanks.

A: 

I think you need to look into jsf a bit more ... ;) What you want to achieve is show user something on the basis of params passed in the url.

That can be achieved by using preRenderView Event of JSF in your view.

 <f:metadata>
    <f:viewParam name="team" value="#{teamEditView.team}"/>
 </f:metadata>
 <f:event type="preRenderView" listener="#{teamEditView.setup}"/> 

Here you can have a method named "setup" in your managed bean which will be invoked and all you pulling data from the datasource can be done in this method on the basis of param passed in the url, which here matches to team

xxxx.faces?team=jsf

you will get this value in your bean and you can fire up as mentioned....

and about jee6 and jsf 2, they have matured a long way wait till you do stuff in pre jee6 versions and jsf, you are lucky to have started with jsf2, its a huge improvement over 1.2 and once you get used to it, it rocks.

Learning curve is a bit but where is it not...... :)

If you are spring lover give CDI a try :)

Sorry mate I don't understand how f:event/f:viewParam helps me in this instance. I've got a BookShelf.xhtml view that renders a list of books in the db. For each book, i want to allow the user to click on it and go to a BookDetails page. So unless I use a combination of <h:form><h:commandLink> and <f:param> tags, I can't achieve the desired result... JSF has made a simple one line <a href="viewBook?id=x"> into more than 4+ lines of code...
Dzhu
+1  A: 

Spring MVC is a request based MVC framework. JSF is a component based MVC framework. That's the difference. Use the one if you want request based MVC and use the other if you want component based MVC.

Seeing this "nonsensicial" construction -in JSF terms-, I'll bet that you've actually a table of books in a h:dataTable and are attempting to obtain the current selected book. If that is indeed the case, then you don't need to pass parameters around at all. Use DataModel<Book> instead to display the books in the h:dataTable, get rid of f:param and update your bean as follows:

@ManagedBean
@ViewScoped
public class BookController {
    private DataModel<BookDTO> bookModel;
    private BookDTO book;

    public String viewBook() {
        book = bookModel.getRowData();   
        return "BookView";
    }

    // ...
}

For a CRUD example in JSF 2.0, you may find this article useful.

BalusC
actually, i just have <ul><c:forEach items="books" var="book"><li>(output cover/link)</li></c:forEach></ul>, the idea of outputting <table> elements doesn't appeal to me. Are you saying that instead of the BookController, I should have BookShelf bean, and a BookDetails bean? I'm confused what do you mean by 'nonsensical' construction in JSF terms?
Dzhu
m... interesting, just had a look at the linked article, I think i'm starting to see the component based 'paradigm'... Is there anything else besides the dataTable? where can I find the source code to it? i wanna see how it implements such logic...
Dzhu
Tomahawk component library offers `t:dataList` which renders `<ul><li>`. The renderer of the `h:dataTable` in Mojarra can be found in `com.sun.faces.renderkit.html_basic.TableRenderer`. In a `c:forEach` your best bet is using `f:setPropertyActionListener` instead of `DataModel`. JSTL doesn't run in sync with JSF. I'd recommend using a JSF component. See also for example my answer on [this question](http://stackoverflow.com/questions/3442380/jstl-cif-inside-a-jsf-hdatatable).
BalusC
thanks very much
Dzhu