Discussions

News: RestFaces1.2 improves bookmarking support for JavaServer Faces

  1. JavaServer Faces is a powerful framework, but it doesn't cover some important areas of web applications - at least, not natively. However, its great extensibility gives us the ability to work around many of its apparent limitations. One of the limitations is bookmarking. JSF uses POST to send data to the framework from the client browser; clearly this is a barrier to bookmarking and indexing, both of which are very important for content applications, where users should expect to be able to bookmark articles or references, for example. Many frameworks extending JSF try to fill this void: Seam, Shale, Gravel, RI Sandbox and RestFaces. The latest RestFaces release (documentation)provides the following benefits:
    • Invocation of actions with parameters using a simple GET request (a la Struts or Spring MVC)
    • Setting bean properties before action invocation, again using GET parameters. In this way actions can read parameters' values and save their state with the bean.
    • support for URI parameters. Some developers feel that /book?id=123 is not elegant as /book/123. RestFaces can manage both type of parameters.
    • Automatic management of parameters in links: it autorenders parameters (query and URI) as desired.
    • Conditional execution of methods listening on page load events (for example it can execute an action just before the "page.jsp" is rendered).
    With the latest release you can configure RestFaces through a set of annotations. Here is a simple example of what the new RestFaces annotations look like: @Instance("#{booksBean}") public class BooksBean { ... @HttpAction(name="bookAction",pattern="book/{id}") public String getBookById(@Param(name="id") long id) { this.book = ...; return "/book.jsp"; } @ViewListener(pattern="/home.jsp") public String onLoadHomePage() { this.list = populateBookList(); return null; } } Now, a URL like /faces/book/123 will trigger execution of the getBookById method.
  2. This looks great Alberto! Just what I'm looking for. Congratulations on this release. Ian Hlavats JSFToolbox: Design JSF Pages in Dreamweaver
  3. Thanks a lot, also because your suggestions about JSR311 has become the inspiration for this release. Thanks to comunity feedbacks I wanted to insert two new important features in 1.2 version: path paremeters and annotations. I gave a look at JSR311 and looked interesting to me. Anyway this is absolutely not an implementation of this JSR. JSR311 is for webservices, instead RestFaces only helps about bookmarking. For example @Param was an idea taken from it.
  4. Hi Alberto, I downloaded and tried out your RestFaces library in a simple JSF application. My initial impression is good and I have some questions/comments about how JSF navigation is supported. Let's look at your example again: @HttpAction(name="bookAction",pattern="book/{id}") public String getBookById(@Param(name="id") long id) { this.book = ...; return "/book.jsp"; } By returning the desired view ID "/book.jsp", your method is telling the JSF navigation handler to forward to /book.jsp. Now, my question is what if I want to redirect to /book.jsp? You recommend in the documentation to return an outcome string and declare a redirect navigation rule in faces-config.xml like so: * success /book.jsp Fine, but what if I want to redirect back to the current view that invoked the method (e.g. Post-Redirect-Get back to the same view)? A null action method outcome tells the JSF navigation handler to redisplay the current view (forward, not redirect). Unfortunately, you can't specify #{view.viewId} in faces-config.xml and I was wondering if you see an opportunity here to support dynamic navigation in RestFaces. For example, what if I want to redirect to a non-Faces URL (e.g. third-party site) after the method returns? I know it is possible to perform this with lower-level calls to the ExternalContext, HttpServletResponse, etc. but then if I'm not using the JSF navigation system why do I have to return a String? Keep up the good work, Ian JSFToolbox for Dreamweaver
  5. You recommend in the documentation to return an outcome string and declare a redirect navigation rule in faces-config.xml like so:



    *

    success
    /book.jsp



    Hi Ian, ok sometimes could be maybe usefull a redirect in a @HttpAction method. Anyway keeep in mind that you would loose bookmarking feature: the resulting page is not bookmarkable.
    Fine, but what if I want to redirect back to the current view that invoked the method (e.g. Post-Redirect-Get back to the same view)?
    Could you provide a valid use case for this? RestFaces works stateless, it has not concept of "current view id", because we are using GET. Maybe if you need something like that you should use a commandLink etc. Am I wrong?
    Unfortunately, you can't specify #{view.viewId} in faces-config.xml and I was wondering if you see an opportunity here to support dynamic navigation in RestFaces.
    Yes, I could write a custom navigation handler.
    For example, what if I want to redirect to a non-Faces URL (e.g. third-party site) after the method returns?

    I know it is possible to perform this with lower-level calls to the ExternalContext, HttpServletResponse, etc. but then if I'm not using the JSF navigation system why do I have to return a String?
    For this specific case you should use the JSF ExternalContext object, as you said. "void" return type is permitted. I think external link shouldn't appear in the nagivation rules. Maybe methos should return String, void or a Navigation object: public Navigation method() { //Redirect implements Navigation return new Redirect("www.google.it"); } or public Navigation method() { return new Redirect("/home.jsp"); } Do you prefer this or a more complex faces-config.xml? Thanks for feedbacks.
  6. Hi Ian,
    ok sometimes could be maybe usefull a redirect in a @HttpAction method. Anyway keeep in mind that you would loose bookmarking feature: the resulting page is not bookmarkable.

    Why would you lose the bookmarking feature? A redirect should be just as bookmarkable as a forward. Consider the pull-style MVC approach. If the redirected URL contains the URI parameters needed to reconstruct the view, then it shouldn't matter if the URL was reached via forward or redirect. I try to design all my JSF views in this way (i.e. they can be reconstructed from query and/or URI parameters) and I strongly prefer redirection over forwarding to prevent the double-submit problem (Post-Redirect-Get).
    Could you provide a valid use case for this?
    Suppose you have a blog page that when you submit the form (to add a new blog entry) you want to redirect to the blog page itself to update the view. This will do two things: (1) it will display the latest blog entry, and (2) it will prevent the user from re-submitting the form (if they click the refresh button on the browser).
    Yes, I could write a custom navigation handler.
    That would be cool. If you could redirect to a non-Faces URL via faces-config.xml or by returning a URL string or Navigation object from the method I think this would be valuable.
    I think external link shouldn't appear in the nagivation rules.
    Why not? If it can be specified in the method return value, for consistency it would be nice to be able to specify it in faces-config.xml too. (Navigation is navigation, after all and consistency in framework design is a good think. Remember the principle of least surprise.)
    Maybe methos should return String, void or a Navigation object:


    public Navigation method() {
    //Redirect implements Navigation
    return new Redirect("www.google.it");
    }


    or


    public Navigation method() {
    return new Redirect("/home.jsp");
    }


    Do you prefer this or a more complex faces-config.xml?

    Thanks for feedbacks.
    I prefer power, flexibility and consistency. If I can do it one way, I would like to be able to do it another way too. It really helps to have options and not to be limited to one particular approach. I would recommend String, void, or Navigation (as you propose) as valid method return types and the ability to specify EL expressions such as #{view.viewId} and literal strings (absolute or context-relative URLs) in faces-config.xml. This way we can have more dynamic navigation and we are not limited to navigating within the JSF application itself. Thanks again! Ian
  7. Just to clarify: I really like your idea about the different return types. By the way, the @ViewListener annotation is great!