Quantcast
Channel: OmniFaces & JSF Fans
Viewing all 74 articles
Browse latest View live

[OmniFaces utilities (2.3)] Send a file to the response whose content is provided via given output stream callback

$
0
0

[OmniFaces utilities] The sendFile() sends a file to the response whose content is provided via given output stream callback. The content type will be determined based on file name. The content length will not be set because that would require buffering the entire file in memory or temp disk. The client may receive a download of an unknown length and thus the download progress may be unknown to the client. If this is undesirable, write to a temp file instead and then use Faces#sendFile(File, boolean). The FacesContext#responseComplete() will implicitly be called after successful streaming.

Note The caller should preferably not catch the IOException thrown by this method,but just re-declare it in the action method.The Servlet container will handle it.

Method

Usage

The relative path of the file to download is /resources/default/images/rafa.png and the user should see at download the file as rafaelnadal.png:

import org.omnifaces.util.Callback;
import org.omnifaces.util.Callback.Output;
import org.omnifaces.util.Faces;
...
public void downloadFile() throws IOException {
 Faces.sendFile("rafaelnadal.png", true, new Callback.Output() {
  @Override
  public void writeTo(OutputStream output) throws IOException {

   FacesContext facesContext = FacesContext.getCurrentInstance();
   ExternalContext externalContext = facesContext.getExternalContext();

   Path path = Paths.get(externalContext.getRealPath("/resources/default/images/rafa.png"));

   long contentLength = (long) Files.getAttribute(path, "basic:size", NOFOLLOW_LINKS);
   if (contentLength != -1) {
       externalContext.setResponseHeader("Content-Length", String.valueOf(contentLength));
   }

   long size = 0;

   try (ReadableByteChannel inputChannel = Channels.newChannel(Files.newInputStream(path));
        WritableByteChannel outputChannel = Channels.newChannel(output)) {
        ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
        while (inputChannel.read(buffer) != -1) {
               buffer.flip();
               size += outputChannel.write(buffer);
               buffer.clear();
        }
   }

   if (contentLength == -1 && !Faces.getExternalContext().isResponseCommitted()) {
       externalContext.setResponseHeader("Content-Length", String.valueOf(size));
   }
  }
 });
}

Or, you can obtain the same thing by using several OmniFaces utilities:

import org.omnifaces.util.Callback;
import org.omnifaces.util.Callback.Output;
import org.omnifaces.util.Faces;
import org.omnifaces.util.Utils;
...
public void downloadFile() throws IOException {
 Faces.sendFile("rafaelnadal.png", true, new Callback.Output() {
  @Override
  public void writeTo(OutputStream output) throws IOException {
   long size = Utils.stream(Faces.getResourceAsStream("/resources/default/images/rafa.png"), output);
   if (!Faces.getExternalContext().isResponseCommitted()) {
        Faces.getExternalContext().setResponseHeader("Content-Length", String.valueOf(size));
   }
  }
 });
}


[JSF Page Author Beginner's Guide] JSF

$
0
0
The <f:convertNumber/> convert a String to a number
 of required format (it also acts as a validator 
to ensure the input value is a valid number)
Common/basic usage in JSF (I) - use <f:convertNumber/>to convert the value of the closest parent UIComponent to a number. For example,  the <f:convertNumber/> converter is commonly attached to inputs like below (here it is attached to an <h:inputText/>):

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
 <h:head>
  <title>JSF convertNumber examples</title>
 </h:head>
 <h:body>
  <h:form>
   <h:panelGrid columns="3">
    <h:outputLabel value="Enter a number:" for="nr1Id"/>
     <h:inputText id="nr1Id" value="#{numberBean.nr1}" label="Enter a number">
      <f:convertNumber />
     </h:inputText>
     <h:message for="nr1Id" style="color:red;"/>
    </h:panelGrid>
   <h:commandButton value="Send" action="#{numberBean.send1()}"/>
  </h:form>
 </h:body>
</html>

The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private Double nr1;

 public NumberBean() {
 }

 // Getters and setters

 public void send1() {
  System.out.println("nr1 = " + nr1);
 }
}

If case that the <f:convertNumber/>cannot successfully convert the provided value to a number it will throw a ConverterExceptionwith an error message like Enter a number: 'foo' is not a number. Example: 99.

Common/basic usage in JSF (II) - Use <f:convertNumber/>converter to "preserve" only the integer part of a number. The integerOnlyattribute is a  flag specifying whether only the integer part of the value will be formatted and parsed. Expressions must evaluate to a boolean. Default value is false.

<h:form>
 <h:panelGrid columns="2">
  <h:outputLabel value="Enter a number:" for="nr2Id"/>
  <h:inputText id="nr2Id" value="#{numberBean.nr2}" label="Enter a number">
   <f:convertNumber integerOnly="true"/>
  </h:inputText>
 </h:panelGrid>
 <h:commandButton value="Send" action="#{numberBean.send2()}"/>
</h:form>

The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private Integer nr2;

 public NumberBean() {
 }

 // Getters and setters

 public void send2() {
  System.out.println("nr2 = " + nr2);
 }
}

Now, if the user enters a number with decimals then only the integer part of the number part will "pass through" the converter (e.g. for 234.12 it will remain 234).

Data flow in image (converter success):
Data flow in image (converter failure):
More examples:

Format a number as currency depending on locale

<f:view locale="en_US">
 Price (default locale):  
 <h:outputText value="#{numberBean.price}">
  <f:convertNumber type="currency" /><!-- uses the en_US locale -->
 </h:outputText>
 Price (locale: ro_RO):  
 <h:outputText value="#{numberBean.price}">
  <f:convertNumber type="currency" locale="ro_RO" />
 </h:outputText>
 Price (locale: de_DE):
 <h:outputText value="#{numberBean.price}">
  <f:convertNumber type="currency" locale="de_DE" />
 </h:outputText>
</f:view>

The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private BigDecimal price = new BigDecimal(2645.5);

 // Getters and setters
}

The result will be rendered in HTML as in figure below:

Set a currency symbol when formatting a number as currency

Price (£):
<h:outputText value="#{numberBean.price}">
 <f:convertNumber type="currency" currencySymbol="£" />
</h:outputText>
Price ($):
<h:outputText value="#{numberBean.price}">
 <f:convertNumber type="currency" currencySymbol="$" />
</h:outputText>
Price (€):
<h:outputText value="#{numberBean.price}">
 <f:convertNumber type="currency" currencySymbol="€" />
</h:outputText>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private BigDecimal price = new BigDecimal(2645.5);

 // Getters and setters
}

Format a number using a custom pattern

Price:
<h:outputText value="#{numberBean.price}">
 <f:convertNumber pattern="###,###.### €" />
</h:outputText>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private BigDecimal price = new BigDecimal(2645.5);

 // Getters and setters
}

Format a number as percentage

Discount:
<h:outputText value="#{numberBean.discount}">
 <f:convertNumber type="percent" />
</h:outputText>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private Number discount = 0.05;

 // Getters and setters
}

Set the minimum number of digits that will be formatted in the fractional portion

Price:
<h:outputText value="#{numberBean.price}">
 <f:convertNumber type="currency" minFractionDigits="1" />
</h:outputText>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private BigDecimal price = new BigDecimal(2645.5);

 // Getters and setters
}

Remove grouping separators when formatting a number into currency

Price:
<h:outputText value="#{numberBean.price}">
 <f:convertNumber type="currency" groupingUsed="false" />
</h:outputText>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private BigDecimal price = new BigDecimal(2645.5);

 // Getters and setters
}

Using the OmniFaces formatBytes() function to format a value as B, KiB, MiB

Format 742 into byte: <h:outputText value="#{of:formatBytes(742)}" />
Format 4735 into kibibyte: <h:outputText value="#{of:formatBytes(4735)}" />
Format 6863463 into mebibyte: <h:outputText value="#{of:formatBytes(6863463)}" />

Will be rendered in HTML as in figure below:

Using the OmniFaces formatPercent() function to format a given number as percentage

<h:graphicImage name="default/images/AeroPro_drive.jpg"
                title="Discount: #{of:formatPercent(numberBean.discount)}"/>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private Number discount = 0.05;

 // Getters and setters
}

Using the OmniFaces formatNumberDefault() function to format a given number in the locale-default pattern

<h:graphicImage name="default/images/AeroPro_drive.jpg"
                title="Price: #{of:formatNumberDefault(numberBean.price)}"/>

Will be rendered in HTML as in figure below:
The managed bean is listed below:

@Named
@RequestScoped
public class NumberBean {

 private BigDecimal price = new BigDecimal(2645.5);

 // Getters and setters
}

Using the OmniFaces formatCurrency() function to format a given number as currency with the given symbol

<h:graphicImage name="default/images/AeroPro_drive.jpg"
                title="Price: #{of:formatCurrency(169, '$')}"/>

Will be rendered in HTML as in figure below:

Using the OmniFaces formatNumber() function to format a given number in the given pattern

<h:graphicImage name="default/images/AeroPro_drive.jpg"
                title="Price: #{of:formatNumber(169, '#.0 €')}"/>

Will be rendered in HTML as in figure below:

Complete source code on GitHub.
See also Mkyong.com.
More resources on Constantin Alin, ZEEF page.
Converters in JSF Extensions on JSF ShowCase ZEEF page.

JSF Navigation Tutorial - The three golden rules of use

$
0
0
Check also:
JSF Navigation Tutorial - Implicit Navigation
JSF Navigation Tutorial - Declarative Navigation

We can talk for hours and hours about JSF navigation, but there are at least three golden rules that save us from falling for the most common mistakes when we need to choose between GET and POST. It might be useful to know that:

• It is recommended to use the GET request for page-to-page navigation, search forms, URLs that you want to be visible and bookmarkable, and, in general, for any idempotent request. By specification, GET, HEAD, PUT, DELETE, OPTIONS, and TRACE are idempotent.

Navigating via JSF GET request with <h:link/> and <h:button/>:



Navigating via non-JSF GET request with <h:outputLink/>:



• For requests that shouldn't be bookmarkable or use the same view repeatedly use POST and forward, not redirect.

Submitting and navigating via JSF POST request with <h:commandLink/> and <h:commandButton/> (using forward mechanism)


• For requests that shouldn't be bookmarkable, but have bookmarkable targets, use POST and redirect (PRG via faces-redirect).

Submitting and navigating via JSF POST request with <h:commandLink/> and <h:commandButton/> (using redirect mechanism)


See you in next post about JSF Implicit Navigation

Check OmniFaces article in Oracle Java Magazine

$
0
0
I've just wrote an article about OmniFaces in Oracle Java Magazine (January/February 2016)

JSF Navigation Tutorial - Implicit Navigation

$
0
0
Check also:
The three golden rules of use
JSF Navigation Tutorial - Declarative Navigation
JSF VS Series: Implicit Navigation VS Declarative (explicit) Navigation

Implicit navigation is available starting with JSF 2 and is the most common type of navigation used in JSF applications. Until JSF 2, we had to declare all navigation cases in faces-config.xml which was a time consuming task and the result was snippets of XML code hard to maintain. By implicit navigation we don't need the declarative approach anymore and specifying simple navigation cases become pretty straightforward. JSF provides a mechanism for mapping logical outcomes to actual web pages. Now, we have two types of implicit navigation: with no explicit navigation outcome and with explicit navigation outcome.

The simplest implicit navigation case is accomplished by JSF itself whenever you perform an action (request) and no navigation is indicated. When an outcome is indicated the implicit navigation interprets navigation outcomes as target view IDs.


So implicit navigation save us from the tedious task of declaring navigation rules in faces-config.xmland provides us a very intuitive and easy to use mechanism of navigation. Whenever we want to navigate back to the current view, we simply do nothing! What could be simpler than that? Whenever we want to navigate to another view, we simply specify the corresponding outcome in the outcome or action attribute depending on the used navigation tag.

Let's see some examples of using implicit navigation. The managed bean used in the next examples is listed first and the application is named ImplicitNavigation:

@Named
@RequestScoped
public class TheBean {
   
 private static final Logger LOG = Logger.getLogger(TheBean.class.getName());
           
 public void theActionWithVoid(){
  LOG.info("TheBean#theActionWithVoid() called ...");
 }

 public String theActionWithViewID() {
  LOG.info("TheBean#theActionWithViewID() called ...");
  return "success.xhtml";
 }

 public String theActionWithExternalURL() {
  LOG.info("TheBean#theActionWithExternalURL() called ...");
  return "http://showcase.omnifaces.org/";
 }
   
 public String theActionWithOutcome(){
  LOG.info("TheBean#theActionWithOutcome() called ...");
  return "success";
 }
   
 public String theActionWithRedirect(){
  LOG.info("TheBean#theActionWithRedirect() called ...");
  return "success?faces-redirect=true;";
 }   
}

FIRE A JSF GET REQUEST AND NAVIGATE BACK TO THIS VIEW ID
Since there is no outcome JSF will consider this page as the targeted page name

<h:link value="Click me!"/>
<h:button value="Click me!"/>

JSF will render the following HTML (as you see the navigation cases have been hard-coded in page source code):

<a href="/ImplicitNavigation/faces/index.xhtml">Click me!</a>

<input type="button" onclick="window.location.href='/ImplicitNavigation/faces/index.xhtml'; return false;" value="Click me!" />

FIRE A JSF GET REQUEST AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
JSF will interpret the outcome value of <h:link/>/<h:button/> as the targeted page name (success becomes success.xhtml)

<h:link value="Click me!" outcome="success"/>
<h:button value="Click me!" outcome="success"/>

JSF will render the following HTML (as you see the navigation cases have been hard-coded in page source code and they contain success.xhtml):

<a href="/ImplicitNavigation/faces/success.xhtml">Click me!</a>

<input type="button" onclick="window.location.href='/ImplicitNavigation/faces/success.xhtml'; return false;" value="Click me!" />

FIRE A JSF GET REQUEST. PROVIDE THE NAVIGATION OUTCOME VIA A SERVER-SIDE METHOD CALLED DURING COMPUTING THE VIEW ID (AT RENDERING TIME)
JSF will interpret the outcome value of of <h:link/>/<h:button/> as the targeted page name (success returned by theActionWithOutcome() becomes success.xhtml)

<h:link value="Click me!" outcome="#{theBean.theActionWithOutcome()}"/>
<h:button value="Click me!" outcome="#{theBean.theActionWithOutcome()}"/>

JSF will render the following HTML (as you see the navigation cases have been hard-coded in page source code and they contain success.xhtml):

<a href="/ImplicitNavigation/faces/success.xhtml">Click me!</a>

<input type="button" onclick="window.location.href='/ImplicitNavigation/faces/success.xhtml'; return false;" value="Click me!" />

Note The server-side method must return a string representing the outcome.

FIRE A GET REQUEST THAT DOESN'T INTERACT WITH JSF
The <h:outputLink/> will navigate independently of JSF (that means it doesn't interact with JSF)

<h:outputLink value="success.xhtml">Click me!</h:outputLink>
<h:outputLink value="http://showcase.omnifaces.org/">OmniFaces Showcase</h:outputLink>

JSF will render the following HTML (as you see the navigation cases have been hard-coded in page source code; notice that /faces is missing!):

<a href="success.xhtml">Click me!</a>
<a href="http://showcase.omnifaces.org/">OmniFaces Showcase</a>

FIRE A GET REQUEST THAT DOESN'T INTERACT WITH JSF. PROVIDE THE NAVIGATION TARGET VIA A SERVER-SIDE METHOD CALLED DURING COMPUTING THE VIEW ID (AT RENDERING TIME)
The <h:outputLink/> will navigate independently of JSF (that means it doesn't interact with JSF)

<h:outputLink value="#{theBean.theActionWithViewID()}">Click me!</h:outputLink>
<h:outputLink value="#{theBean.theActionWithExternalURL()}">OmniFaces Showcase</h:outputLink>

JSF will render the following HTML (as you see the navigation cases have been hard-coded in page source code; notice that /faces is missing!):

<a href="success.xhtml">Click me!</a>
<a href="http://showcase.omnifaces.org/">OmniFaces Showcase</a>

Note The server-side method must return a string representing the navigation target NOT an outcome (e.g. you must return success.xhtml, not success). Since the fired GET request will not pass through JSF  the outcome will not be computed!

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM AND NAVIGATE BACK TO THIS VIEW ID
Since there is no action JSF will consider this page as the targeted page name

<h:form>
 <h:commandLink value="Click Me!"/>
 <h:commandButton value="Click Me!"/>
</h:form>

JSF will render the following HTML (as you see the navigation cases are not hard-coded). Even if we have a HTML <a> and an <input type="submit">  there is no functional difference between them. Both will submit the form and navigate back to the current view ID.

<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt30'),{'j_idt30:j_idt32':'j_idt30:j_idt32'},'');return false">
 Click Me!
</a>

<input type="submit" name="j_idt30:j_idt34" value="Click Me!" />

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM. INVOKE A VOID ACTION METHOD AND NAVIGATE BACK TO THIS VIEW ID
There is an action but it points to an void action method. JSF will invoke the theBean#theActionWithVoid() action method and consider this page as the targeted page name

<h:form>
 <h:commandLink value="Click Me!" action="#{theBean.theActionWithVoid()}"/>
 <h:commandButton value="Click Me!" action="#{theBean.theActionWithVoid()}"/>
</h:form>

JSF will render the following HTML:

<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt36'),{'j_idt36:j_idt38':'j_idt36:j_idt38'},'');return false">
 Click Me!
</a>

<input type="submit" name="j_idt36:j_idt40" value="Click Me!" />

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
JSF will interpret the action value of <h:commandLink/Button/> as the targeted page name (success becomes success.xhtml)

<h:form>
 <h:commandLink value="Click Me!" action="success"/>
 <h:commandButton value="Click Me!" action="success"/>
</h:form>

JSF will render the following HTML:

<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt42'),{'j_idt42:j_idt44':'j_idt42:j_idt44'},'');return false">
 Click Me!
</a>

<input type="submit" name="j_idt42:j_idt46" value="Click Me!" />

FIRE (SUBMIT) A POST REQUEST VIA REDIRECT MECHANISM AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
The presence of ?faces-redirect=true; will instruct JSF to rely on POST-redirect-GET (PRG) navigation pattern

<h:form>
 <h:commandLink value="Click Me!" action="success?faces-redirect=true;"/>
 <h:commandButton value="Click Me!" action="success?faces-redirect=true;"/>
</h:form>

JSF will render the following HTML:

<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt48'),{'j_idt48:j_idt50':'j_idt48:j_idt50'},'');return false">
 Click Me!
</a>

<input type="submit" name="j_idt48:j_idt52" value="Click Me!" />

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM. INVOKE AN ACTION METHOD AND NAVIGATE TO THE VIEW ID COMPUTED BASED ON THE OUTCOME RETURNED BY THIS METHOD
The action can point to an action method that returns a String. This string is considered the outcome and it will be interpreted as the targeted page name (success becomes success.xhtml)

<h:form>
 <h:commandLink value="Click Me!" action="#{theBean.theActionWithOutcome()}"/>
 <h:commandButton value="Click Me!" action="#{theBean.theActionWithOutcome()}"/>
</h:form>

JSF will render the following HTML:

<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt54'),{'j_idt54:j_idt56':'j_idt54:j_idt56'},'');return false">
 Click Me!
</a>

<input type="submit" name="j_idt54:j_idt58" value="Click Me!" />

FIRE (SUBMIT) A POST REQUEST VIA REDIRECT MECHANISM. INVOKE AN ACTION METHOD AND NAVIGATE TO THE VIEW ID COMPUTED BASED ON THE OUTCOME RETURNED BY THIS METHOD
The action can point to an action method that returns a String suffixed with ?faces-redirect=true; (will instruct JSF to rely on POST-redirect-GET (PRG) navigation pattern). This string is considered the outcome and it will be interpreted as the targeted page name (success becomes success.xhtml)

<h:form>
 <h:commandLink value="Click Me!" action="#{theBean.theActionWithRedirect()}"/>
 <h:commandButton value="Click Me!" action="#{theBean.theActionWithRedirect()}"/>
</h:form>

JSF will render the following HTML:

<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt60'),{'j_idt60:j_idt62':'j_idt60:j_idt62'},'');return false">
 Click Me!
</a>

<input type="submit" name="j_idt60:j_idt64" value="Click Me!" />

The complete application is available here.

Notes
Logic of outcome
When implicit navigation takes place it follows the next steps:

1.Look for the ? character in the logical outcome. If it is found then capture the query string and look for the presence of faces-redirect=true request parameter. Remember that this parameter points to a redirect navigation case.

2.Look for the file extension attached to the logical outcome. If none is found then automatically attached the extension of current view ID (e.g. xhtml)

3.If the logical outcome doesn't begin with a / then prepend the location of the current view ID (e.g., /, /pages/, etc.).

4. Locate the view ID. If it is not found then abort implicit navigation.

5.For non-redirect cases simply build and render the view ID in the current request. If it is a redirect then build a redirect URL. The query string parameters captured earlier is appended to this URL. Redirect to this URL.

Use Sub-folders
If your views are stored in subfolders then simply prefix the outcome with the corresponding path (e.g. if the view login.xhtml is stored in /mypages/credentialsfolder then an outcome will be: mypages/credentials/login).

Use Application Context
Whenever you want to add the application context path in a URL (for example, the URL generated via <h:outputLink>, you can use the ExternalContext.getApplicationContextPath method of JSF 2.2. For example, take a look at the following code:

<h:outputLink value="#{facesContext.externalContext.applicationContextPath}/next.xhtml">Next</h:outputLink>

Forward vs Redirect
By default, between forward and redirect, JSF will navigate from one page to another using the forward mechanism (HTTP POST). When JSF receives the user action, it will forward the user to the determined target page, which means that the URL displayed by the browser will not be updated to reflect the current target. Keeping the browser URL updated implies the page redirection mechanism; in this case, JSF, delegates the browser to send a separate GET request to the target page. You can use the page redirection mechanism by attaching the faces-redirect=trueas you saw in the above examples. In the forward case, the browser URL is not updated (is with a step behind navigation URL), but there is a single request. In the redirect case, the browser URL is up to date, but there are two requests. Since forward needs a single request, it is faster than page redirection. The speed is lower, but page redirection solves the duplicated form submission problem found in the Post-Redirect-Get design pattern. Of course, this is not the case for <h:link/>, <h:button/>, and <h:outputLink/>.
We can conclude that POST via forward result in non-bookmarkable URL while POST via redirect result in bookmarkable URL and this is a major SEO aspect also.

Outcome vs View ID
In all the examples above we have used the outcome version (success) instead of view ID (success.xhtml).  In not a good idea to use view ID directly since you may decide to give up on *.xhtml mapping and use *.jsf. In such case, you will have to modify the success.xhtml in success.jsf. This will happen for all such navigation cases. Using the successoutcome will not require any further adjustments.

Outcome vs Action
If you are a novice then is very possible to confuse these two attributes. Basically, the outcome attribute is specific to <h:link/> and <h:button/>tags. Its role is to point to the logical outcome used to resolve a navigation case and the tags that support it cannot submit a form. On the other hand, the action attribute is specific to commands capable to submit forms (<h:commandLink/>and <h:commandButton/>).  This attribute is a String representing the logical outcome or a MethodExpressionrepresenting the application action to invoke when this component is activated by the user. The expression must evaluate to a public method that takes no parameters, and returns an Object(the toString()of which is called to derive the logical outcome) which is passed to the NavigationHandler for this application. 

[OmniFaces utilities 2.3] Expose protected state helper into public

$
0
0

[OmniFaces utilities] The getStateHelper() method exposes protected state helper into public.

Method:
Usage:

import org.omnifaces.util.Hacks;
...
StateHelper stateHelper = Hacks.getStateHelper(foo_component);
// now use the StateHelper API via stateHelper object

NoteDo not forget about the OmniFaces State utils for finding/putting a value associated with the specified key in the component's state.

JSF linking together components, renderers and render kits

$
0
0
Introduction

In order to understand what a render kit is we have to be aware of some major notions that are very important in this context. For a better understanding please check out the below picture and identify the notions described here, and the relationships between them. The subject of this picture is the OmniFaces DeferredScriptcomponent, but don't worry, you don't have to understand that component. The role and functionality of this component is not our goal. We use it because it is a professional approach for writing custom components and sustains the topic of this article by exposing best practices of accomplishing such tasks.


A JSF component is annotated with @FacesComponent and it is characterized by three coordinates (we won't take here into account the declarative approach):

component-family -This is a piece of information that groups more components under the same family/category (e.g. ScriptFamily - a family of components that deals with scripts). Typically, a family of components are logically related, but there is no written rule. Nevertheless, a family name can be represented by the package name that holds the classes of the related components (e.g. org.omnifaces.component.script). It is a common practice that the classes of the components that are related to be placed in the same package, so the package name can be considered a family. But, again, there is no rule to sustain this practice. In order to expose into public is family a component will override the getFamily() method. Since JSF 2.2, the component-type can be omitted in @FacesComponent, because JSF will determine it like this (ComponentConfigHandler class):

...
String value = ((FacesComponent) annotation).value();
if (null == value || 0 == value.length()) {
    value = target.getSimpleName();
    value = Character.toLowerCase(value.charAt(0)) + value.substring(1);
}
...

component-type - This is a piece of information that uniquely identifies a component and can be used as the argument of the Application.createComponent(java.lang.String) method for creating instances of the UIComponent class. JSF uses the component-type for creating components. Typically a component type will be the fully qualified named of the component class (e.g. org.omnifaces.component.script.DeferredScript). There is a common practice to define the component-typeas a static finalstring directly in component class and to name it COMPONENT_TYPE. Some developers tend to place the component-typestring directly in annotation, which somehow restricts the programmatic access to this information, since, by default, there is no public UIComponent.getComponentType()method to override. Components of different types can be grouped in families.

renderer-type - This is a piece of information that uniquely identifies a renderer (e.g. org.omnifaces.DeferredScript). A component will used its setRendererType()method to point to the render-typethat should render this component. Components can call this method as setRendererType(null)to point out that they will render themselves. But, by delegating the rendering to a separate renderer, the component makes itself more versatile because multiple renderers would be able to render it to different clients.

If you extend UIInput, you will inherit its type and family, but if you extend UIComponentBase, then you need to explicitly provide the component-type and component-family.

A Renderer is not selected based on the component-type and renderer-type! Is selected based on component-family and renderer-type, which allows a renderer to be used for multiple components in the same family. The component-typeis used for creating components in view root!

Overview of Renderer

What is the main goal of a renderer ?
Is responsible to decode the values from the incoming request and to encode the values to be displayed by transforming the component tree into the HTML markup that will be displayed to the client machine. Shortly, to transform a JSF component in markup (e.g. HTML, XML, etc).

When you commonly need a custom renderer ?
When you need to render a custom component (brand new or extension of a built-in one), because none of the built-ins do what you want to achieve.

When you want to alter the look/functionality of an built-in component.

What should I know before start writing a custom renderer ?
Mainly you need to know that a renderer extends directly/indirectly the Renderer class.
Starting with JSF 2.2, you can extend RendererWrapper, which is a simple implementation of Renderer. JSF 2.2 comes with many wrappers, which are simple implementations of what they are wrapping, and they help developer to override only the necessary methods, and to provide specialized behavior to an existing wrapped instance (e.g. RendererWrapper can be used for providing specialized behavior to an existing Renderer instance). The wrapped instance is available via the getWrapped()method.

The main three methods of a Renderer are encodeBegin(), encodeChildren() and encodeEnd(). By default, JSF calls them in this order, and the first one usually renders the beginning of the markup - "open" tags (e.g. <head>, <input>, <form>, etc), the second one  renders the children (this is configurable via getRendersChildren()flag), and the last one is ending the markup - "close" tags (e.g. </head>, </input>, </form>).

In order to link a component with a renderer, you should know how to work with the UIComponent.setRenderType()method and with the component-family, component-typeand renderer-typeartifacts as level of annotations or with the <render-kit>  and <renderer> tags in faces-config.xml.

How do I usually write a Renderer skeleton ?
•when you write a brand new component (extending UIComponentBase), you will extend the Rendererclass directly and override most of its methods. Usually in these cases you will link the custom component with the renderer via annotations and setRendererType()method.


More examples:

Create and render a brand new component (source code).

When you write a custom component which extends a built-in component, you usually extend the renderer of the built-in component also - directly (most probably) or indirectly. Usually in these cases you will link the custom component with the renderer via the setRenderType() method. Of course, you can also use the renderer of the built-in component without any modifications (source code).
When you just want to alter a built-in component at rendering level, you usually extend the built-in renderer and you instruct JSF to use your renderer instead of the default one via faces-config.xml, <renderer> tag. E.g. use a custom Renderer for the JSF UIOutputcomponent (source code). In order to run this application you have to keep in mind that we are extending a Mojarra renderer (com.sun.faces.renderkit.html_basic.TextRenderer), so you need to:

- manually install the JSF 2.2 JAR so your IDE will find the TextRenderer.
- in pom.xml, the entry for JSF 2.2 should have its scope set to provided, as it shouldn't be copied into the deployment.

Overview of RenderKit

What is the main goal of a RenderKit ?
While the Rendererclass converts the internal representation of UI components into markup (e.g. HTML), RenderKitrepresents a collection of Rendererinstances capable to render JSF UI component's instances for a specific client (for example, a specific device). Each time JSF needs to render a UI component, it will call the RenderKit.getRenderer()method which is capable of returning an instance of the corresponding renderer based on two arguments that uniquely identifies it: the component-family and the renderer-type. Moreover, RenderKitregisters renderers via RenderKit.addRenderer()method based on the component-family, renderer-typeand Renderer instance. When we write a correct renderer (respecting the JSF specification) JSF will automatically find it and register it for us.

When you commonly need a custom RenderKit ?
You may use a custom RenderKitto instruct JSF to delegate renderers in a specific approach. Per example, a custom RenderKitcan choose the right renderer depending on device (PC, tablet, iPhone, etc). Or, you may have a custom Rendererthat extends the RendererWrapper, and use a custom RenderKitto pass an instance of an existing Renderer to the custom Renderer.

What should I know before start writing a custom RenderKit ?
Mainly, you need to know that a custom RenderKit extends directly/indirectly the RenderKit class.

Starting with JSF 2.0, you can extend RenderKitWrapper, which is a simple implementation of RenderKit. Via RenderKitWrapper, you can provide a specialized behavior to an existing RenderKit instance. The wrapped instance is available via the getWrapped()method.

The main two methods of a RenderKit are addRenderer() and getRenderer(). By overriding these methods, you can take control over the Renderers registration and delegation. Of course, there are many other useful methods listed in documentation.

How do I usually write a RenderKit skeleton ?
Usually, you will extend the RenderKitWrapper class, override the necessary methods, and configure it in the faces-config.xmlvia <render-kit>tag.

So, as you can see in figure below, the RenderKit sits between components and renderers and act as a conductor:

Now, we know that each component is rendered after its component-family and renderer-type passes through the RenderKit.getRenderer()method:

public abstract Renderer getRenderer(java.lang.String family,
                                     java.lang.String rendererType)

This method match the correct renderer , like this:

private ConcurrentHashMap<String, HashMap<String, Renderer>> rendererFamilies =
  new ConcurrentHashMap<String, HashMap<String, Renderer>>();
...
HashMap<String,Renderer> renderers = rendererFamilies.get(family);
return ((renderers != null) ? renderers.get(rendererType) : null);

So, in order to obtain its renderer, each component must reveal its family (COMPONENT_FAMILY) and renderer-typeto this method (with a simple custom RenderKit you can check out the JSF/OmniFaces components families and renderer types). Programmatically, a family, component-family, is obtained via UIComponent.getFamily(), and the renderer-typevia UIComponent.getRendererType():

public abstract java.lang.String getFamily()
public abstract java.lang.String getRendererType()

Now, JSF search through available renderers that was added via RenderKit.addRenderer().  JSF has inspected faces-config.xml file for:

<render-kit>
    <renderer>
        <component-family>component-family</component-family>
        <renderer-type>renderer-type</renderer-type>
        <renderer-class>RendererClass</renderer-class>
    </renderer>
</render-kit>

 and all classes annotated with @FacesRenderer:

@FacesRenderer(componentFamily=ComponentClass.COMPONENT_FAMILY, rendererType= RendererClass.RENDERER_TYPE)
public class RendererClass extends Renderer {
 public static final String RENDERER_TYPE = "renderer-type";
 ...
}

Optionally, Facelets can be also informed by the render type in *taglib.xml. When you do that, you instruct Facelets to create a component of the given component-type. The component class is annotated with @FacesComponent or has been defined in faces-config.xml. In addition Facelets will set to the given renderer type.

<tag>
 ...
 <component>
  <component-type>component-type</component-type>
  <renderer-type>renderer-type</renderer-type>
 </component>
 ...
</tag>

Ok, so now let's have several examples of custom RenderKits:

Log how JSF renderers are added/delegated by JSF (source code).

Instruct JSF to render all components of a family via a common custom renderer (we simply apply a common CSS style to all components from javax.faces.Inputfamily) (source code).

Instruct JSF to render UIOutputcomponents via a custom renderer that was registered for other type of components, but pass to it an instance of the original renderer (source code).

Overview of a RendererKitFactory

What is the main goal of a RenderKitFactory ?
It manages (register/provide) instances of available RenderKits.

When you commonly need a custom RenderKitFactory ?
You may use a custom RenderKitFactoryto instruct JSF to delegate RenderKits in a specific approach. By default, JSF has a single RenderKit, identified by an ID, HTML_BASIC_RENDER_KIT. But, if want to write another RenderKitthen you can programmatically choose between them using a custom RenderKitFactory.

What should I know before start writing a custom RenderKitFactory ?
Mainly, you need to know that a render kit factory extends directly/indirectly the RendererKitFactoryclass.

The main two methods of a RenderKitFactory are addRenderKit() and getRenderKit() . By overriding these methods, you can take control over the RenderKits registration and delegation. The render kits IDs can be obtained via getRenderKitIds()method. If this factory has been decorated, the implementation doing the decorating may override the getWrapped()method to provide access to the implementation being wrapped.

In order to link a component with a renderer, you should know how to work with the UIComponent.setRenderType()method and with the component-family, component-typeand renderer-typeartifacts as level of annotations or with the <render-kit>  and <renderer> tag in faces-config.xml.

How do I usually write a RenderKitFactory skeleton ?
Usually, you will extend the RenderKitFactory class, override the necessary methods, and configure it in the faces-config.xmlvia <render-kit-factory>tag.

For example, replace the default JSF RenderKit with the DummyRenderKit (source code).

Updated PrimeFaces&OmniFaces Powers Combined Book


[OmniFaces utilities (2.3)] Parsing the given object representing the locale to a Locale object

$
0
0

[OmniFaces utilities] The parseLocale() method parses the given object representing the locale to a Locale object. If it is null, then return null. Else if it is already an instance of Locale, then just return it. Else if it is in pattern ISO 639 alpha-2/3, optionally followed by "_" and ISO 3166-1 alpha-2 country code, then split the language/country and construct a new Locale with it. Else parse it via Locale#forLanguageTag(String) and return it.

Method
Usage

We will pass to Utils#parseLocale()a string of type xxx_yy. The xxx part represents the ISO 639 alpha-2/3 code, and the yyrepresents the ISO 3166-1 alpha-2 country code. For example for Japan we have, jpn_JP.

<h:form>
 <h:outputText value="Country: #{localeBean.locale.country}"/>
 <h:outputText value="Display Country: #{localeBean.locale.displayCountry}"/>
 <h:outputText value="Display Language: #{localeBean.locale.displayLanguage}"/>

 <h:commandButton value="Japan" action="#{localeBean.localeAction('jpn_JP')}"/>
 <h:commandButton value="Italy" action="#{localeBean.localeAction('ita_IT')}"/>
 <h:commandButton value="Lule Sami" action="#{localeBean.localeAction('smj')}"/>
</h:form>

import org.omnifaces.util.Faces;
import org.omnifaces.util.Utils;
import java.util.Locale;
...
@Named
@RequestScoped
public class LocaleBean {
 
 private Locale locale;
 
 @PostConstruct
 public void init(){       
  // init with the current locale
  locale=Faces.getLocale();
 }

 public void localeAction(String code) {
  locale =  Utils.parseLocale(code);               
 }

 public Locale getLocale() {
  return locale;
 }       
}

The output will be:

// initial
Country: US
Display Country: United States
Display Language: English

// after pressing Japan button
Country: JP
Display Country: the Japan
Display Language: Japanese

// after pressing the Italy button
Country: IT
Display Country: Italy
Display Language: Italian

// after pressing the Lule Sami button
Country:
Display Country:
Display Language: Lule Sami

[OmniFaces utilities (2.3)] Format the given number in the default pattern of the given locale

$
0
0

[OmniFaces utilities] The formatNumberDefaultForLocale() method formats the given number in the default pattern of the given locale. This is useful when you want to format numbers in for example the title attribute of an UI component, or the itemLabel attribute of select item, or wherever you can't use the <f:convertNumber> tag. The given locale can be a Locale object or a string representation.

Method
Usage

We will pass to Numbers#formatNumberDefaultForLocale() a locale of type xx_yy conforming to JDK 8 and JRE 8 Supported Locales, but we will pass a string of type xxx_yy also. The xxx part represents the ISO 639 alpha-2/3 code, and the yy represents the ISO 3166-1 alpha-2country code. For example for Japan we have, jpn_JP. Moreover, we will pass an instance of current Locale:

@Named
@RequestScoped
public class AmountBean {
   
 private double amount = 10242556643.23d;

 public double getAmount() {
  return amount;
 }       
}

// 10,242,556,643.23
<h:outputText value="Amount (Japan): #{of:formatNumberDefaultForLocale(amountBean.amount, 'jpn_JP')}"/>

// 10.242.556.643,23
<h:outputText value="Amount (Romania): #{of:formatNumberDefaultForLocale(amountBean.amount, 'ro_RO')}"/>

// 10 242 556 643,23
<h:outputText value="Amount (France): #{of:formatNumberDefaultForLocale(amountBean.amount, 'fr_FR')}"/>

// 10,242,556,643.23
<h:outputText value="Amount (Lule Sami): #{of:formatNumberDefaultForLocale(amountBean.amount, 'smj')}"/>

// 10,242,556,643.23
<h:outputText value="Amount (your locale): #{of:formatNumberDefaultForLocale(amountBean.amount, facesContext.viewRoot.locale)}"/>

In practice we can use it whenever <f:convertNumber/> is not an option. For example, we can used for formatting the value of itemLabel, as below:

@Named
@RequestScoped
public class AmountBean {

 private double amount;   
 List<Double> amounts;
   
 @PostConstruct
 public void init(){       
      
  amounts = new ArrayList<>();
       
  amounts.add(6943.322d);
  amounts.add(119033933.2d);
  amounts.add(444055493302.22222d);
  amounts.add(775.2133d);
  amounts.add(21331.2200d);
 }

 public double getAmount() {
  return amount;
 }
 public void setAmount(double amount) {
  this.amount = amount;
 }       

 public List<Double> getAmounts() {
  return amounts;
 }       
}

<h:form>
 <h:panelGrid columns="3">
  <h:selectOneMenu value="#{amountBean.amount}">
   <f:selectItems value="#{amountBean.amounts}" var="t"
                  itemLabel="#{of:formatNumberDefaultForLocale(t, 'ro_RO')}" itemValue="#{t}"/>
  </h:selectOneMenu>
  <h:commandButton value="Select amount"/>
  <h:outputText value="Selected amount (Romania): #{of:formatNumberDefaultForLocale(amountBean.amount, 'ro_RO')}"/>
 </h:panelGrid>
</h:form>

Validating multiple fields by a custom validator method or by a managed bean instance which implements the MultiFieldValidator interface

$
0
0
The OmniFaces <o:validateMultiple/> allows the developer to validate multiple fields by either a custom validator method or, by a managed bean instance which implements the MultiFieldValidatorinterface. In the first approach, the method that performs the validation must respect the following signature:

public class FooBean {
 // ...
 public boolean fooMethod(FacesContext context, List<UIInput> components, List<Object> values) {
  // ...
 }
 // ...
}

And, it is referenced from <o:validateMultiple/> like below:

<o:validateMultiple ... validator="#{fooBean.fooMethod}" />

In the second approach, we implement the MultiFieldValidator interface and override the validateValues() method:

@Override
public class FooBean implements MultiFieldValidator {
 // ...
 public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
  // ...
 }
 // ...
}

And, it is referenced from <o:validateMultiple/> like below:

<o:validateMultiple ... validator="#{fooBean}" />

Let's have an examples that uses the second approach. For this let's suppose that we have a PrimeFaces PickList and a SelectManyCheckbox. Both components will be populated with the same data and our validation constraint imposes that the selected data from the PickList should contain the data checked in the SelectManyCheckbox. Before we add the validation constrains, let's have some preparations. So, let's say that the used data are instances of the Player class listed below:

public class Player implements Serializable {

 private static final long serialVersionUID = 1L;

 private int rank;
 private String name;

 public Player(int rank, String name) {
  this.rank = rank;
  this.name = name;
 }

 // getters and setters

 // This method is needed for using the OmniFaces ListConverter
 // and SelectItemsConverter. Both need  that our entity has a
 // good toString() implementation
 @Override
 public String toString() {
  return "Player{" + "rank=" + rank + ", name=" + name + '}';
 }
}

Furthermore, let's create a few Players and let's prepare the data accordingly to PickList and SelectManyCheckbox requirements:

@Named
@ViewScoped
public class PlayerBean implements Serializable {

 private static final long serialVersionUID = 1L;

 private List<Player> players;
 private List<Player> selectedviaCheckbox;
 private DualListModel<Player> model;

 @PostConstruct
 public void init() {
  selectedviaCheckbox = new ArrayList<>();
  players = asList(
   new Player(8, "Tomas Berdych"),
   new Player(20, "Jurgen Melzer"),
   ...
  );

  model = new DualListModel<>(
          new ArrayList<>(players),
          new ArrayList<Player>()
  );
 }

 // getters and setters

 // some dummy action
 public void playersAction(){
  Messages.addGlobalInfo("The selected players are valid");
 }
}

Next, we can expose this data to the user (notice that we have used the omnifaces.ListConverter for PickList and omnifaces.SelectItemsConverter for SelectManyCheckbox.

<h:form>
 <p:messages id="msgs"/>
 <p:pickList id="playersList" value="#{playerBean.model}" var="t"
             itemLabel="#{t.rank}.#{t.name}" itemValue="#{t}">
  <o:converter converterId="omnifaces.ListConverter" list="#{playerBean.players}" />
 </p:pickList>

 <p:selectManyCheckbox id="playersCheckbox" value="#{playerBean.selectedviaCheckbox}"
                       converter="omnifaces.SelectItemsConverter"
                       layout="responsive" style="width: 435px; margin-top: 5px;" columns="3">
  <f:selectItems value="#{playerBean.players}" var="t"
                 itemLabel="#{t.rank}.#{t.name}" itemValue="#{t}" />
 </p:selectManyCheckbox>

 <p:commandButton value="Submit" action="#{playerBean.playersAction()}"
                  update="msgs" style="margin-top:5px" />           
</h:form>

At this moment any combination of selections will be valid, as you can see in figure below:


Is time for ValidateMultiple to enter in the scene! As we said earlier, we will implement the MultiFieldValidator interface and override the validateValues() method. This method receives a list of UIInputs representing the input components that enters in validation and a list of Objects representing the local values of these components (these are the values that should be validated). Now, we need to provide the code specific to our validation constraint. We can accomplish this in multiple ways, but notice that our list of components contains two instances: one instance of org.primefaces.component.picklist.PickList and one instance of org.primefaces.component.selectmanycheckbox.SelectManyCheckbox; moreover, the list of values should contain an instance of org.primefaces.model.DualListModel and an instance of List):

@Named
@ApplicationScoped
public class ValidatePlayers implements MultiFieldValidator {

 @Override
 public boolean validateValues(FacesContext fc, List<UIInput> components, List<Object> values) {

  List<Player> fromModel;

  if (values.get(0) instanceof DualListModel) {
      fromModel = ((DualListModel) values.get(0)).getTarget();
      return fromModel.containsAll((List) values.get(1));
  } else {
      fromModel = ((DualListModel) values.get(1)).getTarget();
      return fromModel.containsAll((List) values.get(0));
  }
 }
}

Finally, we need to use <o:validateMultiple/> in page. This is pretty straightforward:

<h:form>
 ...
 <o:validateMultiple id="validateMultiple"
                     components="playersList playersCheckbox"
                     validator="#{validatePlayers}"
                     message="The selected players via checkboxes must be contained by the selected player list." />
</h:form>

This time the selection from above picture is not valid. Checkout the figure below:


But, if in the PickList, we also select the Pablo Cuevas and Jeremy Chardy players then the submission will become valid:


The complete application is named ValidateMultiple.

Read more such goodies in:

PrimeFaces & OmniFaces - Powers Combined

JSF built-in debug component

$
0
0
The <ui:debug/>tag (ComponentHandler) defines a debug component in the component tree that is capable of capturing debugging information such as component tree, scoped variables, and view state. For example, you can add the <ui:debug/>tag into a page using the following code:

<ui:debug hotkey="q" rendered="true"/>

Now, when you press Ctrl + Shift + Q, you will see something like the following screenshot:

[OmniFaces utilities (2.3)] Remove server side JSF view state associated with current request

$
0
0

[OmniFaces utilities] The removeViewState() method remove server side JSF view state associated with current request.

Method

Moreover, see also the private helpers:


Usage:

In order to remove the current view we need to pass to Hacks#removeViewState()  the current FacesContext, ResponseStateManagerand view ID. For example:

<h:commandButton value="Click me to remove view state!" 
                 action="#{viewBean.removeViewStateAction()}"/>

import org.omnifaces.util.Faces;
import org.omnifaces.util.FacesLocal;
import org.omnifaces.util.Hacks;
...
public void removeViewStateAction() {
 FacesContext facesContext = Faces.getContext();
 RenderKit renderKit = FacesLocal.getRenderKit(facesContext);
 ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
 String viewId = Faces.getViewId();

 Hacks.removeViewState(facesContext, responseStateManager, viewId);         
}
   
OmniFaces uses this method internally in RestorableViewHandlerfor removing the current view and returning the restored(new created) one:

@Override
public UIViewRoot restoreView(FacesContext context, String viewId) {
 if (isUnloadRequest(context)) {
     UIViewRoot createdView = createView(context, viewId);
     ResponseStateManager manager = getRenderKit(context).getResponseStateManager();

     if (restoreViewRootState(context, manager, createdView)) {
         context.setProcessingEvents(true);
         context.getApplication().publishEvent(context, PreDestroyViewMapEvent.class, UIViewRoot.class, createdView);
        Hacks.removeViewState(context, manager, viewId);
     }

     responseComplete();
     return createdView;
 }

 UIViewRoot restoredView = super.restoreView(context, viewId);

 if (!(isRestorableViewEnabled(context) && restoredView == null && context.isPostback())) {
     return restoredView;
 }

 try {
     UIViewRoot createdView = buildView(viewId);
     return isRestorableView(createdView) ? createdView : null;
 } catch (IOException e) {
     throw new FacesException(e);
 }
}

JSF VS Series: The VS

[OmniFaces utilities (2.3)] Get the Internet Protocol (IP) address of the client that sent the request

$
0
0

[OmniFaces utilities] The getRemoteAddr() method returns the Internet Protocol (IP) address of the client that sent the request. This will first check the X-Forwarded-For request header and if it's present, then return its first IP address, else just return HttpServletRequest#getRemoteAddr() unmodified.

Method:

Usage:

  • inside a servlet filter or even a plain vanilla servlet (basically, when FacesContext is not available):
import org.omnifaces.util.Servlets;
...
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
 protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // e.g. 'remoteAddr' may be '0:0:0:0:0:0:0:1'
  String remoteAddr = Servlets.getRemoteAddr(request);
 }
 ...
}
  • in JSF, when FacesContext is available use, Faces#getRemoteAddr()or more clumsy (not recommended). 
import org.omnifaces.util.Servlets;
...
// or simply use, Faces#getRequest()
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();

// e.g. 'remoteAddr' may be '0:0:0:0:0:0:0:1'
String remoteAddr = Servlets.getRemoteAddr(request);

API GH

JSF Navigation Tutorial - Declarative Navigation

$
0
0
Check also:
The three golden rules of use
JSF Navigation Tutorial - Implicit Navigation
JSF VS Series: Implicit Navigation VS Declarative (explicit) Navigation

Declarative navigationrefers to defining the navigation cases in faces-config.xml via a bunch of dedicated tags. Before implicit navigation, this was the only way to navigate after an action. These days  the implicit navigation is available, so declarative navigation is considered obsolete (officially speaking they are not obsolete or deprecated!). But, since this is a navigation tutorial we cannot simply ignore declarative navigation, therefore let's have a quick intro and some examples.
In order to navigate, JSF needs the well-known coordinates: view ID, logical outcome and/or action expression signature. Only that this time they are described in the faces-config.xmldescriptor using XML-based rules, as follow:

<navigation-rule/>
This tag wraps the navigation cases of a specific view ID.

<from-view-id/>
This is a child of <navigation-rule/>and it defines the view ID from which we navigate.

<navigation-case/>
This is a child of <navigation-rule/>and it wraps a single navigation case characterized by view ID, logical outcome and/or action expression signature. There can be multiple navigation cases.

<from-outcome/>
This tag is a child of <navigation-case/>and represents the logical outcome.

<from-action/>
This tag is a child of <navigation-case/>and represents an action expression signature (optional).

<to-view-id/>
This tag is a child of <navigation-case/>and represents the view ID that resolve the logical outcome and/or action expression signature.

<redirect/>
This tag is a child of <navigation-case/>and instructs JSF that the navigation should be accomplish via PRG. By default, JSF will navigate via POST request based in forward mechanism.

For example, check the below navigation items:

<h:link value="Success" outcome="success"/>
<h:button value="Success" outcome="success"/>

<h:commandButton value="Success" action="success"/>
<h:commandLink value="Success" action="success"/>

The declarative version of this is as follows—thanks to implicit navigation, this code
is not needed:

<navigation-rule>
 <from-view-id>*</from-view-id>
 <navigation-case>
  <from-outcome>success</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

Let's see some more examples. The managed bean used in the next examples is listed first and the application is named DeclarativeNavigation:

@Named
@RequestScoped
public class TheBean {

 private static final Logger LOG = Logger.getLogger(TheBean.class.getName());   

 public String theActionWithDoneOutcome() {
  LOG.info("TheBean#theActionWithDoneOutcome() called ...");
  return "done";
 }
   
 public String theActionWithOutcomeForSuccess() {
  LOG.info("TheBean#theActionWithOutcomeForSuccess() called ...");
  return "doneFromTheActionWithOutcome";
 }
   
 public String theActionWithOutcomeForFailure() {
  LOG.info("TheBean#theActionWithOutcomeForFailure() called ...");
  return "doneFromTheActionWithOutcome";
 }   
   
 public String theActionWithRedirectForSuccess() {
  LOG.info("TheBean#theActionWithRedirectForSuccess() called ...");
  return "doneFromTheActionWithRedirect";
 }
   
 public String theActionWithRedirectForFailure() {
  LOG.info("TheBean#theActionWithRedirectForFailure() called ...");
  return "doneFromTheActionWithRedirect";
 }
}

FIRE A JSF GET REQUEST AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
JSF will interpret the outcome value of <h:link/>/<h:button/> as the targeted page name (done becomes success.xhtmlvia declarative navigation)

<h:link value="Click me!" outcome="done"/>
<h:button value="Click me! " outcome="done"/>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>done</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE A JSF GET REQUEST. PROVIDE THE NAVIGATION OUTCOME VIA A SERVER-SIDE METHOD CALLED DURING COMPUTING THE VIEW ID (AT RENDERING TIME)
JSF will interpret the outcome value of <h:link/>/<h:button/> as the targeted page name (done returned by theActionWithDoneOutcome() becomes success.xhtmlvia declarative navigation)

<h:link value="Click me!" outcome="#‌{theBean.theActionWithDoneOutcome()}"/>
<h:button value="Click me!" outcome="#‌{theBean.theActionWithDoneOutcome()}"/>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>done</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
JSF will interpret the action value of <h:commandLink/Button/> as the targeted page name (done becomes success.xhtmlvia declarative navigation)

<h:form>
 <h:commandLink value="Click Me!" action="done"/>
 <h:commandButton value="Click Me!" action="done"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>done</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE (SUBMIT) A POST REQUEST VIA REDIRECT MECHANISM AND NAVIGATE TO THE VIEW ID COMPUTED FROM THE SPECIFIED OUTCOME
The presence of <redirect/> in navigation case will instruct JSF to rely on POST-redirect-GET (PRG) navigation pattern

<h:form>
 <h:commandLink value="Click Me!" action="doneredirect"/>
 <h:commandButton value="Click Me!" action="doneredirect"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>doneredirect</from-outcome>
  <to-view-id>/success.xhtml</to-view-id>
  <redirect/>
 </navigation-case>
</navigation-rule> 

FIRE (SUBMIT) A POST REQUEST VIA FORWARD MECHANISM. INVOKE AN ACTION METHOD AND NAVIGATE TO THE VIEW ID COMPUTED BASED ON THE OUTCOME RETURNED BY THIS METHOD
The action can point to an action method that returns a String. This string is considered the outcome and it will be interpreted as the targeted page name (doneFromtheActionWithOutcome becomes success/failure.xhtml via declarative navigation)

// theActionWithOutcomeForSuccess() → doneFromTheActionWithOutcome → success.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithOutcomeForSuccess()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithOutcomeForSuccess()}"/>
</h:form>

// theActionWithOutcomeForFailure() → doneFromTheActionWithOutcome → failure.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithOutcomeForFailure()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithOutcomeForFailure()}"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>doneFromTheActionWithOutcome</from-outcome>
  <from-action>#{theBean.theActionWithOutcomeForSuccess()}</from-action>
  <to-view-id>/success.xhtml</to-view-id>
 </navigation-case>
 <navigation-case>
  <from-outcome>doneFromTheActionWithOutcome</from-outcome>
  <from-action>#{theBean.theActionWithOutcomeForFailure()}</from-action>
  <to-view-id>/failure.xhtml</to-view-id>
 </navigation-case>
</navigation-rule>

FIRE (SUBMIT) A POST REQUEST VIA REDIRECT MECHANISM. INVOKE AN ACTION METHOD AND NAVIGATE TO THE VIEW ID COMPUTED BASED ON THE OUTCOME RETURNED BY THIS METHOD
The presence of <redirect/> in navigation case will instruct JSF to rely on POST-redirect-GET (PRG) navigation pattern

// theActionWithRedirectForSuccess() → doneFromTheActionWithRedirect → success.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithRedirectForSuccess()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithRedirectForSuccess()}"/>
</h:form>

// theActionWithRedirectForFailure() → doneFromTheActionWithRedirect → failure.xhtml
<h:form>
 <h:commandLink value="Click Me!" action="#‌{theBean.theActionWithRedirectForFailure()}"/>
 <h:commandButton value="Click Me!" action="#‌{theBean.theActionWithRedirectForFailure()}"/>
</h:form>

Declaratively, we have:

<navigation-rule>
 <from-view-id>index.xhtml</from-view-id>
 <navigation-case>
  <from-outcome>doneFromTheActionWithRedirect</from-outcome>
  <from-action>#{theBean.theActionWithRedirectForSuccess()}</from-action>
  <to-view-id>/success.xhtml</to-view-id>
  <redirect/>
 </navigation-case>
 <navigation-case>
  <from-outcome>doneFromTheActionWithRedirect</from-outcome>
  <from-action>#{theBean.theActionWithRedirectForFailure()}</from-action>
  <to-view-id>/failure.xhtml</to-view-id>
  <redirect/>
 </navigation-case>
</navigation-rule>

The complete application is available here.

JSF VS Series: Implicit Navigation VS Declarative (explicit) Navigation

JavaServer Faces 2.3 Quick Reference

JSF 2.3 - The WebSocket Quickstart under Payara

$
0
0
Read also:

JSF 2.3 - Explicitly open/close a websocket channel
JSF 2.3 - Conditionally open/close a websocket channel
JSF 2.3 - Firing one-time push when the web socket channel has been opened
JSF 2.3 - Multiple File Upload with HTML 5, AJAX and upload progress bar via web sockets

Starting with JSF 2.3-m05 we can take advantage of a brand new feature - register a web socket push connection in client side. Thanks to the JSF team (especially to Bauke Scholtz (aka BalusC)) this feature is available in today milestone via <f:websocket/>tag.

In this post, let's see a minimal usage of <f:websocket/> tag.

In JSF page, we need to add the <f:websocket/> tag with its two required attributes:

·         channel- This is javax.el.ValueExpressionthat must be evaluated to Stringand it represents the name of the web socket channel. A channel name is restricted to alphanumeric characters, hyphens, underscores and periods. A channel can have multiple open web sockets, and each of these sockets will receive the same push notification from the server.
·         onmessage- This is javax.el.ValueExpressionthat must be evaluated to Stringand it represents the a JavaScript listener function that is automatically invoked when a push notification is received from the server.

The signature of the listener function for onmessage is of type:

function fooListener(message, channel, event) {                      
 // message - the message pushed by the server
 // channel - the channel name
 // event - the raw MessageEvent instance
}

So, a simple <f:websocket/>tag usage will look like this:

<f:websocket channel="clock" onmessage="socketListener" />

<div id="clockId"></div>

<script type="text/javascript">
 function socketListener(message, channel, event) {                      
  document.getElementById("clockId").innerHTML += message + "<br/>";
 }
</script>

By default, when we start the application, the web socket is automatically connected and open. As long as the document is open the web socket is open. When the document is unloaded the web socket is automatically closed. In the web socket is initially successfully connected but the connection is closed as a result of e.g. a network error or server restart, JSF will try to auto-reconnect it at increasing intervals.

Now, let's focus on the server side. Here we have to take into account the push messages mechanism. This mechanism is based on javax.faces.push.PushContext interface and javax.faces.push.PushAPI.

First, you need to know that by default the web socket is application scoped. This means that the managed bean that can push messages to this web socket must be in application scope (annotated with @ApplicationScope). In this case, the push message can be sent by all users and the application itself.

Furthermore, you have to inject PushContext via @Push annotation on the given channel name in any CDI/container managed artifact. For example:

@Inject
@Push(channel = "clock")
private PushContext push;

Finally, we need to write an action method capable to push messages to web socket via PushContext. For example:

public void clockAction(){
 Calendar now = Calendar.getInstance();
       
 String time = now.get(Calendar.HOUR_OF_DAY) + ":" +
               now.get(Calendar.MINUTE) + ":" +
               now.get(Calendar.SECOND);
 LOG.log(Level.INFO, "Time: {0}", time);
    
 push.send(time);
}

Let's glue everything together. First, the JSF page:

<h:body>        
 <h:form>           
  <h:commandButton value="Clock" action="#{pushBean.clockAction()}">
   <f:ajax />
  </h:commandButton>
 </h:form>

 <f:websocket channel="clock" onmessage="socketListener" />       

 <hr/>
 <div id="clockId"></div>

 <script type="text/javascript">
  function socketListener(message, channel, event) {                      
   document.getElementById("clockId").innerHTML += message + "<br/>";
  }
 </script>   
</h:body>

Next, our simple CDI bean:

@Named
@ApplicationScoped
public class PushBean implements Serializable {
   
 private static final Logger LOG = Logger.getLogger(PushBean.class.getName());
       
 @Inject
 @Push(channel = "clock")
 private PushContext push;
   
 public void clockAction(){
  Calendar now = Calendar.getInstance();
       
  String time = now.get(Calendar.HOUR_OF_DAY) + ":" +
                now.get(Calendar.MINUTE) + ":" + now.get(Calendar.SECOND);
  LOG.log(Level.INFO, "Time: {0}", time);
       
  push.send(time);
 }
}

Finally, the m05 requires the following settings in web.xml:

<context-param>
 <param-name>javax.faces.ENABLE_CDI_RESOLVER_CHAIN</param-name>
 <param-value>true</param-value>
</context-param>   
<context-param>
 <param-name>javax.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
 <param-value>true</param-value>
</context-param>

Done! The complete application was tested under Payara server and it is available here.

JSF 2.3 - Explicitly open/close a websocket channel

$
0
0
Before you read this post I recommend you to read:


In this post, you will see how to explicitly open/close a channel. By default, a channel is automatically open when we start the application, but this is not always the desired behavior. As a consequence, first we need to instruct JSF to not open our channel automatically, and for this we set the optional channelattribute to false. This attribute can be a javax.el.ValueExpressionthat must be evaluated to boolean, and by default it is set to true.

<f:websocket channel="clock"connected="false" onmessage="socketListener" />

This attribute is re-evaluated on every AJAX request, but since we have set it to false,our channel will never be connected. This give us the freedom to open/close the channel explicitly via JavaScript functions:

jsf.push.open("channelName") - explicitly open a channel
jsf.push.close("channelName") - explicitly close a channel

Since these are JavaScript functions they can be invoked exactly as any other JavaScript function. For example, you can invoke them from a snippet of JavaScript, or from the onclickevent of a button, as below:

<h:form>   
 <h:commandButton value="Open channel"onclick="jsf.push.open('clock')">
  <f:ajax />
 </h:commandButton>
 <h:commandButton value="Close channel"onclick="jsf.push.close('clock')">
  <f:ajax />
 </h:commandButton>
 <h:commandButton value="Clock" action="#{pushBean.clockAction()}">
  <f:ajax />
 </h:commandButton>
</h:form>

Moreover, we may want to be informed when the channel is open/close. For this, we can attach two special JavaScript listeners, as follows:

<f:websocket channel="clock" connected="false"
             onopen="websocketOpenListener"
             onclose="websocketCloseListener"
             onmessage="socketListener" />   

The optional onopenand oncloseattributes are javax.el.ValueExpressionthat must be evaluated to String. These Strings represents the JavaScript listener functions that are invoked when the web socket is opened/closed. The JavaScript listener corresponding to onopen will receive a single argument represented by the channel name. The JavaScript listener corresponding to onclosewill be invoked with three arguments: the close reason code, the channel name and the raw CloseEventitself. Since this function is invoked on errors also, it is a good practice to have it around. Below, you can see two dummy implementation of our listeners:

function websocketOpenListener(channel) {
 alert("Channel " + channel + " was successfully open!");
}

function websocketCloseListener(code, channel, event) {
 if (code == -1) {
     // Web sockets not supported by client.
     alert("Web sockets not supported by client");
 } else if (code == 1000) {
     // Normal close (as result of expired session or view).
     alert("The channel " + channel + " was successfully closed");
 } else {
     // Abnormal close reason (as result of an error).
     alert("The channel " + channel + " was abnormally closed");
 }
}

Now, the interface will look like in figure below:

Explicitly open the channel
Use the opened channel
Explicitly close the channel
When you run the application, you can notice that the Clock button will not "work" until the channel is opened, and will not "work" after the channel is closed. This means that you are controlling the channel status explicitly via Open channel and Close channel buttons.

The complete application is available here.
Viewing all 74 articles
Browse latest View live