Having a "constants"-class in JSF

11,794

How do I achieve this, making the constants accessible from both backing beans and XHTML files?

In backing beans, it's obviously easy. As they're just Java classes, it's not different from the "normal" Java way. You could use enums or public static final fields. In views, this is a different story. Until the upcoming version 3.0, EL does namely not support constants in any way.

I'd suggest using enums as EL has implicit support for them in string comparisons. It does not do any compiletime/runtime type safety checks, but you can use the enum name as a string. E.g.

<h:someComponent ... rendered="#{order.status == 'SHIPPING'}" />

If you prefer more self documenting code and a runtime check (no, a compiletime check is not possible), then you could consider using OmniFaces <o:importConstants>.

<o:importConstants type="com.example.OrderStatus" />
<h:someComponent ... rendered="#{order.status == OrderStatus.SHIPPING}" />

This is IMO only a bit more clumsy. The runtime check is however nice during development. A typo is easily overseen.

In the upcoming EL 3.0 (JSR-341, part of Java EE 7), it's possible to reference constants the same way. See also How to reference constants in EL? This only requires programmatic import of the constants as there's no standard JSP/Facelets tag for that.

Share:
11,794

Related videos on Youtube

javaMS
Author by

javaMS

Updated on September 18, 2022

Comments

  • javaMS
    javaMS over 1 year

    I'm building a web-application using JSF/Primefaces. I need to have a "constants"-class, i.e. a class that will consist of constants. These constants are mainly navigational commands that will be used throughout the application. The reason I am doing this is to avoid having instantiated Strings on an ad-hoc basis.

    How do I achieve this, making the constants accessible from both backing beans and XHTML files?

    I have tried using @ApplicationScoped and using the Singleton-pattern (Singleton class) but I am unable to get it working due to scope issues.

    Or maybe I am just using the wrong approach. Any ideas/suggestions are welcome.

    • Luiggi Mendoza
      Luiggi Mendoza over 11 years
      Why don't you have a class with public static final String page1 = "page1.xhtml". Remember that this class will be used in your managed beans. If you're going to use any of these values in your JSF code, then you could add the @ApplicationScope to the class and getters for the Strings you will use.
    • javaMS
      javaMS over 11 years
      Can you explain with an example?
  • javaMS
    javaMS over 11 years
    I have used enums and they work fine at the bean-level. However, when I try to use omnifaces in order to import the enum I get an exception. My view has this: <p:commandButton action="#{staffbean.add(staffbean.staff, NavigationHelper.ADD_STAFF)}" ajax="false" value="Save" icon="ui-icon-check" /> and then I have public String add(Object object, Object command) { (...) NavigationHelper nh = (NavigationHelper) command; in the bean. Exception is java.lang.NullPointerException
  • javaMS
    javaMS over 11 years
    Ok, I found the problem. I have to place the <o:importConstants/> within the <ui:define/>-block. I had placed it outside of it which led to this exception. Can you explain what you mean by clumsy?
  • BalusC
    BalusC over 11 years
    Tags must indeed be placed inside the view, not outside. If you're using a master template, you can also just place it there, so that you don't need to repeat it over all template clients. "Clumsy" means here "not simple enough". I like simplicity.
  • javaMS
    javaMS over 11 years
    Thanks. I was under the impression that the external boundary-tag for the view was the <composition>-tag.
  • BalusC
    BalusC over 11 years
    In a template client, everything outside <ui:define> isn't part of the view.
  • Ian Evans
    Ian Evans over 10 years
    @BalusC: you might want to edit your answer with the final syntax for constants in EL 3.0.