Recent Posts

RSS Feeds

Ski Socks - Who Knew

Well after years of exhaustive research I've finally discovered the perfect ski sock... I have been using Kirkland brand (Costco for those that don't know) dress socks for the last few times I've gone skiing and they work like a champ. I've tried the $25/pair silk socks, normal white athletic socks etc and nothing works as well as these dress socks. Yes I know its weird but give it a shot. Of course your mileage might vary :-)

Permalink     1 Comment

JSF EA4 and JSF 1.0 Beta changes - Action to MethodBinding

Well this is the first of hopefully many installments on how to convert to the new JSF 1.0 Beta from the EA4 release.

In the old EA4 you would implement an adapter between what JSF expected (i.e. the javax.faces.application.Action interface) and the business method on your java bean. So the code looked something like this...

  private transient Action loginAction = new Action() {
    public String invoke() {
      return login();
    }
  };
...
  public String login() {
    // defautls to valid
    String outcome = VALID_LOGIN_OUTCOME;
    FacesContext ctx = FacesContext.getCurrentInstance();
    try {
      LoginCommand delegate = LoginCommandLocal.getCommand();
      Customer customer =
        delegate.validateLogin(getUserName(), getPassword());
      if (customer != null) {
        Map sessionMap = ctx.getExternalContext().getSessionMap();
        sessionMap.put(CUSTOMER_KEY, customer);
      } else {
        // The customer was null so the login must have failed.
        // Set the outcome to invalid and add an error message
        // to the faces context.
        outcome = INVALID_LOGIN_OUTCOME;
        addLoginNotFoundMessage(ctx);
      }
    } catch (HibernateException e) {
      // something is wrong with the database
      outcome = INVALID_LOGIN_OUTCOME;
      addInternalErrorMessage(ctx);
      // log the exception so someone can fix it
      logger.throwing(getClass().getName(), "login", e);
    } finally {
      // for security purposes set the password to null
      setPassword(null);
    }
    return outcome;
  }

The JSP would contain an 'actionRef' attribute that specified a EL like expression that JSF used to bind the button push (or other User Gesture) to the adapter.

              <h:command_button id="submit" type="SUBMIT"
              	                label="Login" 
              	                commandName="login" 
              	                actionRef="loginPage.loginAction"/>

In the brave new world of 1.0 Beta things are simpler. Instead of having an adapter between your 'business logic' and the JSF component you simply refer to the method you want called via a Method Binding Expression (Section 5.2 of the JSF 1.0 Beta spec). This frees you from having to have one of these little anonymous implementations for each 'action' that happens on a page. As expected this among other things will cause a reworking of part of the presentation but I think that the general idea is still quite valid (basically don't mix your business logic with your view logic). Which I know to many folks this seems to be basic fundamental programming 101, but you would be surprised how often the view and model are mixed...

Enough rambling on to the code...

            <h:command_button action="#{loginPage.login}"
                 value="#{bundle.login}" />
  

The LoginPage code is then altered to remove the loginAction field as well as the get/set method pair. Since UICommand implements ActionSource it will find the MethodBinding specified in the 'action' attribute and then invoke that method binding. (Which for the astute observer might look surprisingly like an adapter, and that is what it is, but its provided by the framework and transparent to us as JSF developers now). The method must take no parameters and return a String. The String that is returned is used as the 'logical outcome' for input into the NavigationHandler.

Overall I really like this, I think it is much more elegant than the EA4 mechanism.

The command_button in this example also has its value set via a properties bundle which is the new and improved localization stuff in the JSF 1.0 Beta but that is a topic for another post.

Sorry not to have linked UICommand, ActionSource and MethodBinding to their JavaDocs but I could not find them publicly @ sun. They are in the javadoc that comes with the 1.0 Beta JSF download though.

I'll post more bits and pieces as I work through the code for the book.

Permalink     No Comments