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

CDI-JSF: Use @Inject to annotate a field of a bean

$
0
0
Most commonly, JSF applications uses dependency injection by annotating private fields with @Inject. We can inject directly an instance of another class (bean) or we can inject an javax.enterprise.inject.Instance and use the get() method to obtain the needed instance:

@Named
@RequestScoped
public class TheBean {

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

 @Inject
 private Foo foo;
 //private Instance<Foo> foo;
   
 @Inject
 private Buzz buzz;
 //private Instance<Buzz> buzz;
   
 @Inject
 private Bizz bizz;   
 //private Instance<Bizz> bizz;

 public void callFooBuzzBizz() {
  LOG.info("TheBean#callFooBuzzBizz() called ...");
  Messages.addGlobalInfo("TheBean#callFooBuzzBizz() called ...");
       
  foo.fooify();
  buzz.buzzify();
  bizz.bizzify();
       
  // foo.get().fooify();
  // buzz.get().buzzify();
  // bizz.get().bizzify();
 }
}

The complete example is available here.

CDI-JSF: Avoid common mistakes that causes ambiguous dependencies errors

$
0
0
After you start using CDI, sooner or later, you will get an error of type: "Ambiguous dependencies for type...". Without too many words, this errors means that CDI should inject a bean into another bean, but it cannot decide what bean to inject.

In CDI, a bean can have multiple beans types (user-defined class or interface) - is important to keep this in mind. For example:

public class Foo extends Buzz implements Bizz {
   ...
}

The bean types are: Foo, Buzz,  Bizzand java.lang.Object.

 If you never saw this error before then probably you are in one of the two most common scenarios from below:

·         a bean type doesn't provide enough information to the container to point out that it should be injected
·         you have multiple beans that "share" bean types, so the container cannot determine the bean type that you are referring

Multiple implementations of the same interface
One of the most common mistakes that result in an ambiguity case consist in injecting an interface that has multiple implementations. For example, let's suppose that you have an interface named FooI:

public interface FooI {
 public void fooify();
}

Furthermore, we have a simple implementation of this interface named Foo1:

public class Foo1 implements FooI {  

 @Override
 public void fooify() {
  ...
 }
}

Now, we can easily inject the Foo1 bean into another bean like this:

@Inject
private FooI foo;

Further, let's suppose that we write another implementation of FooI named, Foo2:

public class Foo2 implements FooI {  

 @Override
 public void fooify() {
  ...
 }
}

At this point, you will see an "Ambiguous dependencies for type..." error. This is happening because the container cannot determine if you want to inject the Foo1bean or the Foo2bean.

You can easily solve this problem (and similar problems) via CDI qualifiers. Basically, a qualifier is a user-defined annotation that is itself annotated with @Qualifier. For example, we can write a qualifier like below:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface F1 {
}

The next thing to do is to annotate the desired bean with this qualifier. For example, let's annotate the Foo1bean:

@F1
public class Foo1 implements FooI {
 ...
}

Once we have done this the application works again, but pay attention that the container will inject an instance of Foo2 bean, NOT Foo1 bean. This is happening because we did not used our qualifier at the injection point! So, if we want to inject an instance of Foo1, we need to do this:

@Inject @F1
private FooI foo;

Now, we can easily inject an instance of Foo1  and Foo2 in the same bean:

@Inject @F1
private FooI foo1;
   
@Inject
private FooI foo2;

Done! The complete application is available here.

Ambiguous dependencies caused by extension
Furthermore, let's see another common case that causes an ambiguous dependency error. For example, let's suppose that we have a simple bean Foo:

public class Foo {
 ...
}

Now, we know that this can be easily injected as:

@Inject
private Foo foo;

Later, in development stage, you extend this bean like this:

public class Buzz extends Foo {
 ...
}

Suddenly the application stop working! Again, you can notice an "Ambiguous dependencies for type..." error. The problem is that our Foo bean has the bean types Foo and java.lang.Object, while the Buzz bean has the Foo, Buzz and java.lang.Object bean types. Even if we can successfully use @Inject Buzz buzz, we cannot use @Inject Foo foo. In first case (@Inject Buzz buzz) the container can uniquely identify the Buzz bean, while in the second case (@Inject Foo foo) the container observe that the Foo and Buzz beans have in common the bean type Foo, and it doesn't know what to inject, a Fooor the Buzzinstance. And this is the cause of the ambiguity.

We can solve this problem using a qualifier as in the previous case, or we can use the @Typedannotation. This annotation allows us to restrict the bean types to an explicit set of classes. For example, we can instruct the container that the Buzz bean has the bean type Buzz, BUT not Foo:

@Typed(Buzz.class)
public class Buzz extends Foo {
 ...
}

Now, the container knows that you want to inject an instance of Foo bean.

The complete application is available here.

Simple example of writing a client behavior

$
0
0
The "client behavior" idea refer to the fact that a client (user) can perform an action over a component (click, blur, focus, mouse over, mouse out, etc) and trigger a specific behavior. As you can see, the actions performed by the user will cause HTML events (e.g. onchange, onclick, onmouseover, onmouseout, onkeydown, onload), and those events will be transformed in behaviors via JavaScript snippets of code that runs on client machine, in his browser. The behaviors was already rendered by JSF as pieces of JavaScript, and there are available on client.

Technically speaking, the ClientBehavior interface (and the ClientBehaviorBase which is a convenience base class that implements the default concrete behavior of all methods defined by ClientBehavior) defines the mechanism by which client behavior implementations generate scripts. The most important method on the ClientBehavior interface is getScript():

public String getScript(ClientBehaviorContext context)

The getScript()method returns a string that contains a JavaScript code suitable for inclusion in a DOM event handler. The method’s single argument, the ClientBehaviorContext, provides access to information that may be useful during script generation, such as the FacesContextand the UIComponentto which the behavior is being attached.

Let's see an example. We simply render a button that is capable to delete some files when is clicked. But, before deleting the files we render a confirmation dialog. The piece of JavaScript that output the confirmation dialog is returned by a ClientBehaviorBase, and the HTML event is onclick- this is the default event for <h:commandButton/>.

1.The index.xhtmlpage looks like this:

<h:body>
 <h:form>
  <h:commandButton value="Delete" action="done">
   <b:confirmDelete/>
  </h:commandButton>
 </h:form>
</h:body>

2.The ClientBehaviorBase looks like this:

@FacesBehavior(value = "confirm")
public class ConfirmDeleteBehavior extends ClientBehaviorBase {  
   
 @Override
 public String getScript(ClientBehaviorContext behaviorContext) {
  return "return confirm('Are you sure you want to delete this file ?');";
 }
}

3.The delete.taglib.xml looks like this:

<facelet-taglib version="2.2"
                xmlns="http://xmlns.jcp.org/xml/ns/javaee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd">

 <namespace>http://www.custom.tags/jsf/delete</namespace>
  <tag>
   <tag-name>confirmDelete</tag-name>
   <behavior>
    <behavior-id>confirm</behavior-id>
   </behavior>
  </tag>
</facelet-taglib>

 

The complete example is available here.

Generic client behavior example

$
0
0
Before checking this application, please get familiar with client behaviors. A simple example is available here.

Now, let's write a generic client behavior example. We simply want to display an image, and react via a JS snippet of code to the following events that occur on this image: onclick, onmouseout, onmouseover, onmousedown and onmouseup.

1.The index.xhtmllooks like this:

<h:body>
 <h:panelGrid columns="2">
  <h:graphicImage library="default" name="pfof.png">
   <b:genericBehavior/>
  </h:graphicImage>
  <div id="behaviorsId" style="width:300px;"/>
 </h:panelGrid>
</h:body>

2.We use a tag handler to programmatically register behaviors:

public class GenericBehaviorTagHandler extends TagHandler {

 private final GenericBehaviorHandler onmouseout = new GenericBehaviorHandler();
 private final GenericBehaviorHandler onmouseover = new GenericBehaviorHandler();
 private final GenericBehaviorHandler onclick = new GenericBehaviorHandler();
 private final GenericBehaviorHandler onmousedown = new GenericBehaviorHandler();
 private final GenericBehaviorHandler onmouseup = new GenericBehaviorHandler();

 public GenericBehaviorTagHandler(TagConfig tagConfig) {
  super(tagConfig);
 }

 @Override
 public void apply(FaceletContext ctx, UIComponent parent) throws IOException {

  if (parent instanceof ClientBehaviorHolder) {
      ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) parent;

      Map<String, List<ClientBehavior>> behaviors = clientBehaviorHolder.getClientBehaviors();

      if (!(behaviors.containsKey("mouseout"))
          && !(behaviors.containsKey("click"))
          && !(behaviors.containsKey("mouseover"))
          && !(behaviors.containsKey("mousedown"))
          && !(behaviors.containsKey("mouseup"))) {

           clientBehaviorHolder.addClientBehavior("mouseout", onmouseout);
           clientBehaviorHolder.addClientBehavior("mouseover", onmouseover);
           clientBehaviorHolder.addClientBehavior("click", onclick);
           clientBehaviorHolder.addClientBehavior("mousedown", onmousedown);
           clientBehaviorHolder.addClientBehavior("mouseup", onmouseup);
      }
   }
 }
}

3.The behaviors are instances of GenericBehaviorHandler:

public class GenericBehaviorHandler extends ClientBehaviorBase {

 @Override
 public String getRendererType() {          
  return "genericbehaviorrenderer";
 }
}

4.And the behavior renderer is:

@FacesBehaviorRenderer(rendererType = "genericbehaviorrenderer")
public class GenericBehaviorRenderer extends ClientBehaviorRenderer {

 @Override
 public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior) {
  return "document.getElementById('behaviorsId').innerHTML += '" + behaviorContext.getEventName() + " |';";
 }
}


The complete example is available here.

Writing a custom exception handler

$
0
0
When an error occurs in a Java program it usually results in an exception being thrown. Java exception handling enables Java applications to handle errors and this is an important aspect in order to write robust and reliable Java applications or components. So, how we choose to throw, catch and handle these exceptions is always an aspect that we should carefully consider. JSF has its own system of treating exceptions. First it defines a super-exception, named FacesException. This class represents general JSF exceptions and usually when you get a FacesException, it wraps the real cause of the exception inside of it - for this we have FacesException#getCause().As a note here, this is the reason for what OmniFaces comes with a set of utilities in its org.omnifaces.util.Exceptions class meant to provide general utility methods with respect to working with exceptions - for example, we can unwrap a caught FacesException until a non-FacesException is found. Beside the FacesException, JSF provides several sub-classes of it specially dedicated for some JSF common exceptions, such as AbortProcessingException, ConverterException, EvaluationException, FaceletException, ProtectedViewException, UpdateModelException, ValidatorException, ViewExpiredException. Probably, the most well known from here we have ConverterException, ValidatorException and ViewExpiredException.

Obviously, when an JSF application causes an exception, JSF is responsible for handle it. With other words, JSF decide how and what to do when an exception occurs. It decide if the exception must be thrown as it is, must be reported in a special case (e.g. with a custom message), must be simply ignored (swallowed) etc. Basically, the unhandled exceptions are queued via ExceptionQueuedEvent, and they are handled by an exception handler. For example, Oracle Mojarra implementation provide two handler exceptions, one is com.sun.faces.context.ExceptionHandlerImpl and another one is com.sun.faces.context.AjaxExceptionHandlerImpl. Basically, both of them (and any other exception handler) acts the same in two simple steps:

- override the handle() method
- iterate over the unhandled exceptions (one by one) and handle them accordingly

Note that OmniFaces comes with two exception handler implementations, FullAjaxExceptionHandler (handle exceptions occurred during a JSF AJAX request) and FacesMessageExceptionHandler(adds every exception as a global FATAL faces message). Both of them are dissected in detail in "Mastering OmniFaces" book.

Now, as you can see, we can have multiple exception handlers, so JSF has decide which one(s) to use? Here is where the ExceptionHandlerFactory enters in the scene. This class is responsible to serve instances of exception handlers. For example, in Oracle Mojarra the implementation of ExceptionHandlerFactory is com.sun.faces.context.ExceptionHandlerFactoryImpl. There is true that here we have a little trick in JSF, because since there are two exception handlers, JSF group them in com.sun.faces.context.AjaxNoAjaxExceptionHandler. It is a simple and very intuitive class, just check out its code line by line:

// Source code from Oracle Mojarra 2.2.9
package com.sun.faces.context;

import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;

public class AjaxNoAjaxExceptionHandler extends ExceptionHandlerWrapper {
   
 private AjaxExceptionHandlerImpl ajaxExceptionHandlerImpl;
 private ExceptionHandlerImpl exceptionHandlerImpl;

 public AjaxNoAjaxExceptionHandler(AjaxExceptionHandlerImpl ajaxExceptionHandlerImpl,
                                          ExceptionHandlerImpl exceptionHandlerImpl) {
  this.ajaxExceptionHandlerImpl = ajaxExceptionHandlerImpl;
  this.exceptionHandlerImpl = exceptionHandlerImpl;
 }

 @Override
 public ExceptionHandler getWrapped() {
  FacesContext fc = FacesContext.getCurrentInstance();
  if (null != fc && fc.getPartialViewContext().isAjaxRequest()) {
      return ajaxExceptionHandlerImpl;
  }

  return exceptionHandlerImpl;       
 }       
}

And the ExceptionHandlerFactoryImpl uses like this:

// Source code from Oracle Mojarra 2.2.9
public ExceptionHandler getExceptionHandler() {
 FacesContext fc = FacesContext.getCurrentInstance();
 ApplicationAssociate myAssociate = getAssociate(fc);

 ExceptionHandler result = new AjaxNoAjaxExceptionHandler(
  new AjaxExceptionHandlerImpl(new ExceptionHandlerImpl(Boolean.TRUE)),
  new ExceptionHandlerImpl(((myAssociate != null) ? myAssociate.isErrorPagePresent() : Boolean.TRUE)));

 return result;
}

We also can have a quick look over the ExceptionHandlerImpl. Especially on the ExceptionHandlerImpl#handle()method:

// Source code from Oracle Mojarra 2.2.9
public void handle() throws FacesException {

 for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext(); ) {
      ExceptionQueuedEvent event = i.next();
      ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
      try {
          Throwable t = context.getException();
 ...
}
  
So, mainly if we think to write a custom exception handler, we have to think to the flow from figure below:

Here it is a custom exception handler factory:

public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {

 private ExceptionHandlerFactory exceptionHandlerFactory;

 public CustomExceptionHandlerFactory(){       
 }
   
 public CustomExceptionHandlerFactory(ExceptionHandlerFactory exceptionHandlerFactory) {
  this.exceptionHandlerFactory = exceptionHandlerFactory;
 }

 @Override
 public ExceptionHandler getExceptionHandler() {
  ExceptionHandler handler = new CustomExceptionHandler(exceptionHandlerFactory.getExceptionHandler());

  return handler;
 }
}

And, the custom exception handler skeleton is:

public class CustomExceptionHandler extends ExceptionHandlerWrapper {

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

 private ExceptionHandler exceptionHandler;

 CustomExceptionHandler(ExceptionHandler exceptionHandler) {
  this.exceptionHandler = exceptionHandler;

  LOG.info("JSF uses the CustomExceptionHandler ...");
 }

 @Override
 public ExceptionHandler getWrapped() {
  return exceptionHandler;
 }

 @Override
 public void handle() throws FacesException {

  LOG.info("JSF invoked CustomExceptionHandler#handle() method ...");

  final Iterator<ExceptionQueuedEvent> queue = getUnhandledExceptionQueuedEvents().iterator();

  // If there's no unhandled exception simply return.
  if (!queue.hasNext()) {
      return;
  }

  /////////////////////////////////////
  // HANDLE THE FIRST EXCEPTION ONLY //
  /////////////////////////////////////
  Throwable throwable = queue.next().getContext().getException();

  // Handle the exception, throwable.
  LOG.log(Level.INFO, "Handling exception: {0}", throwable);

  // Let JSF handle exceptions of type AbortProcessingException.
  if (throwable instanceof AbortProcessingException) {
      return;
  }

  // Remove the exception from the queue.
  queue.remove();

  // in order to find the exception root cause, maybe use here
  // the org.omnifaces.util.Exceptions utilities such as:
  // Exceptions#is() or/and Exceptions#unwrap() methods
  //... HANDLE THE EXCEPTION ...
       
  // Remove all remaining exceptions if you want to fix only the first.
  while (queue.hasNext()) {
         queue.next();
         queue.remove();
  }

  // Give control to the default (or other) exception handler.
  getWrapped().handle();

  //////////////////////////////////////
  // HANDLE ALL OR A CERTAIN EXCEPTION //
  ///////////////////////////////////////
  while (queue.hasNext()) {
         ExceptionQueuedEvent item = queue.next();
         ExceptionQueuedEventContext exceptionQueuedEventContext = (ExceptionQueuedEventContext) item.getSource();

         // Get the excpetion from current iteration.
         Throwable throwable_item = exceptionQueuedEventContext.getException();

         // If you know that you want to handle all exceptions from queue
         // then you can remove the exception from this iteration from the queue.
         queue.remove();

         // Handle the exception at this iteration, throwable_item.
         LOG.log(Level.INFO, "Handling exception: {0}", throwable_item);

         // In order to find the exception root cause, maybe use here
         // the org.omnifaces.util.Exceptions utilities such as:
         // Exceptions#is() or/and Exceptions#unwrap() methods
         //...
         // If you want to handle a certain exception place here the conditions to
         // identify it. Also, remove from the queue only this exception
         // (pay attention to not remove unhandled exceptions, only if you intend to do so):
         queue.remove();
         //... HANDLE THE EXCEPTION OF THIS ITERATION ...
           
         // Eventually, if you don't want to handle more exception then break the loop.
         break;
  }

  // Give control to the default (or other) exception handler.
  getWrapped().handle();
 }
}

You can find this skeleton here.

CDI-JSF: Referencing a producer method via an EL name

$
0
0
Here it is an example of using referencing a producer method via an EL name. The EL expressions used in the JSF page:

#{someFoo}
#{moreFoo}

The Fooqualifier:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Foo {
}

And the bean containing the producer method:

@Named
@ApplicationScoped
public class TheBean {

 @Produces
 @Named
 @Foo
 String getSomeFoo() {
  return "foo";
 }       
   
 @Produces
 @Named("moreFoo")
 @Foo
 String getExtraFoo() {
  return "extra-foo";
 }  
}

The complete example is available here.

PrimeFaces dynamic TabView and Hibernate lazy loading

$
0
0
The PrimeFaces TabViewcomponent supports a flag attribute named dynamic (defaults to false). When this attribute is set to true, PrimeFaces will load only the content of the initial opened tab, while the rest of content is loaded via AJAX only when the user clicks on tabs.

So, let's image that we have the following simple database with two tables:


Now, for each category, we want to create a tab, and each tab to be loaded dynamically. We can write something like below:

<h:form id="form">
 <p:tabView dynamic="true" cache="true">          
  <p:tab title="My Site">               
   Check out our categories
  </p:tab>
  <c:forEach items="#{dataBean.allCategories}" var="t">           
   <p:tab title="#{t.name}">
    <p:dataList value="#{t.productsCollection}" var="q" type="ordered">
     <f:facet name="header">
      Products
     </f:facet>
     #{q.product} 
    </p:dataList>
   </p:tab>          
  </c:forEach>
 </p:tabView>
</h:form>

Ok, so the first tab is just a dummy tab that doesn't contain data from the database. While the rest of tabs reflect the names and number of available categories. Notice that we have set dynamic="true", and moreover we have set cache="true". This means that caching only retrieves the tab contents
once and subsequent toggles of a cached tab does not communicate with server.

Now, let's take a quick look to our code used for querying database. We  can use Hibernate JPA, and the relevant part is:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "categories", fetch = FetchType.EAGER)
private Set<Products> productsCollection;

Notice that Hibernate is by default lazy, so we manually turned fetching to eager.

Now, if we run the application we see the following output:


Notice that our tab is not even containing data from database. Is just a dummy tab with some intros. But, since the rest of tab's names are actually our categories names, the application must hit the database. If we check the log we notice that even if load only the names of the categories, Hibernate will load the products from each category also. Obviously, this is the effect of eager loading.

Moreover, when we click on a tab of a category, this is happening again until all tabs are cached. Now, we may want to switch to the default Hibernate fetching style, which is LAZY(simply delete the fetchelement, or manually set it):

@OneToMany(cascade = CascadeType.ALL, mappedBy = "categories", fetch = FetchType.LAZY)
private Set<Products> productsCollection;

When the application starts, everything looks fine. We query only the categories names. But, when we click on other tab, we get an error of type: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: javaee.entites.Categories.productsCollection. Well, this is a well-known Hibernate exception caused by the fact that Hibernate cannot hit the database to initialize the proxy objects since the connection is already closed.

There are a few approaches to solve this issue, like:

Use  PersistenceContextType.EXTENDED with @Stateful EJB - This works only in JEE and the container will manage the database transactions. But, you have to pay attention to the number of stateful beans because they may cause memory issues.  The N+1 issue is also a risk.

Load collection by join - for example, in our case we can go for a left join fetch of type: SELECT c FROM Categories c LEFT JOIN FETCH c.productsCollection. But, this needs a new query to access each model class collection (lazy) attribute. Against this disadvantage, we have some advantages like the fact that we fire a single query in the database and will bring only the desired data. Moreover, the N+1 issue is not a risk.

EclipseLink- This is an alternative to Hibernate JPA that works via a LAZY strategy (hint) that can be set for the persistent provider. This way the persistent provider will know that you expect those data lazy.  Moreover, the N+1 issue is not a risk.

Load collection by Open Session in View - This is basically a solution that relies on keeping a database connection opened until the end of the user request. The implementation is based on a filter that handles the transactions. The N+1 is also a risk, and there are no really advantages of this approach.

We can chose here the first approach. So, we wrote a Stateful bean as below:

@Stateful
public class CategoriesAndProducts {

 @PersistenceContext(unitName = "javaee_PrimeFacesHibernateLazy_war_1.0PU", type=PersistenceContextType.EXTENDED)
 private EntityManager em;

 public List<Categories> getCategoriesAction() {
  TypedQuery<Categories> query = em.createNamedQuery("Categories.findAll", Categories.class);
  List<Categories> results = query.getResultList();

  return results;
 }
}

Now, when we click on a tab, Hibernate will query only the products from the selected category. You can try yourself an implementation via left join also.


The complete example is available here. You can easily run it with MySQL 5 and WildFly 10.

JSF 2.3 - Generating a JavaScript function in the global JavaScript scope which allows the end user to execute a JSF AJAX request by just a function call in the JavaScript context

$
0
0
Sometimes, it may be useful to encapsulate the AJAX requests in JavaScript functions placed in the JavaScript global scope in such way that we can simply call them by name, without arguments, or with arguments that represent the data that should be passed to the server‐side via the encapsulated AJAX request. Obviously the jsf.ajax.request()and mojarra.ab()functions donʹt allow us to accomplish that, but as you will see, JSF 2.3(and OmniFaces) will call the jsf.ajax.request()from a JavaScript global scoped function that can be easily called by its name.

Letʹs take a look at this simple HTML code:

<h5>Your Feedback About JSF 2.3: </h5>
<div>
 Your Name: <input id="userId" type="text"/>
 <p id="feedbackId" contenteditable="true">type your feedback here</p>
</div>
<br/>
<button onclick="sendFeedback();">Send Feedback</button>

Note that the sendFeedback()function should be defined as a global scoped JavaScript function capable to fire an JSF AJAX request. The user name and feedback should be added as parameters of the AJAX request.

JSF 2.3 comes with a handy new component named CommandScript (starting with JSF 2.3.0-m06) which is capable to solve this kind of tasks. This component be used by the page authors via the <h:commandScript/>tag. This component extends the javax.faces.component.UICommand(<h:commandXxx/>) which means that it inherits the major features of JSF commands, like action, actionListener, immediate, etc. Moreover, this component also supports nesting of <f:param/>, <f:actionListener/>and <f:setPropertyActionListener/>, exactly as in <h:commandXxx/>.

In addition, the foundation of CommandScript consists of the fact that it can generate a JavaScript function in the global JavaScript scope. Via this function call, the end‐user can execute JSF AJAX requests. There are two requirements for this component:

- The nameattribute is mandatory, and it indicates the name of the generated JavaScript function (you can define namespaced function name also by using a dot, ".", inside the function name).
- The <h:commandScript/>must be nested in a <h:form/>.

For example, the simplest way to use <h:commandScript/>, is listed below:

<h:form>
 <h:commandScript name="sendFeedback"/>
</h:form>

This example is correct, but is doesnʹt do much! Basically, it generates in page a snippet of code as below:

<span id="j_idt5:j_idt6">
 <script type="text/javascript">
  var sendFeedback=function(o){
   var o=(typeof o==='object')&&o?o:{};
   mojarra.ab('j_idt5:j_idt6',null,'action',0,0,{'params':o})
  }
 </script>
</span>

It is important to notice that this is just a simple JSF AJAX request, so when we call the sendFeedback()function, we will fire an ʺemptyʺ JSF AJAX request. Obviously, we are interested to control the values of the executeand renderattributes. This is very simple, because <h:commandScript/> supports the execute and render attributes exactly as <f:ajax/>, so we can do this:

<h:form>
 <h:commandScript name="sendFeedback"execute="@form" render=":savedId"/>
</h:form>

Now, the generated code becomes:

<span id="j_idt5:j_idt6">
 <script type="text/javascript">
  var sendFeedback=function(o){
   var o=(typeof o==='object')&&o?o:{};
   mojarra.ab('j_idt5:j_idt6',null,'action','@form','savedId',{'params':o})
  }
 </script>
</span>

With just a snap of a finger we can add the action:

<h:form>
<h:commandScript name="sendFeedback" execute="@form"
                 render=":savedId"action="#{feedbackBean.send()}"/>
</h:form>

So far, so good! If you donʹt have extra information to pass to the server‐side, or it is collected from the form (e.g. <h:inputText/>), then this should be enough. But, in our case we have extra information to pass and this information comes through plain HTML code, so we have to find a solution for adding this information into the JSF AJAX request. Thanks to the <h:commandScript/>the generated function also supports a JavaScript object as an argument which will then end up in the HTTP request parameter map (donʹt forget about <f:param/>). In order to pass an object to the generated function, we need to wrap its call into a global JavaScript function, as below:

<h:outputScript>
 function sendFeedbackWrapper(){
  sendFeedback({user: document.getElementById("userId").value,
  feedback: document.getElementById("feedbackId").innerHTML });
 }
</h:outputScript>

And modify the button as:

<button onclick="sendFeedbackWrapper();">Send Feedback</button>

On the server‐side, the passed information can be easily extracted via the OmniFaces Faces#getRequestParameter()utility method:

String user = Faces.getRequestParameter("user"); // user
String feedback = Faces.getRequestParameter("feedback"); // feedback

Or, we can use the JSF pure solution:

Map<String, String> params = FacesContext.getCurrentInstance().
                                  getExternalContext().getRequestParameterMap();
       
String user = params.get("user"); // user
String feedback = params.get("feedback"); // feedback

The complete application is available here. The application was tested under Payara 4 with JSF 2.3.0-m06.

CDI-JSF: Inject a Java logger via a CDI producer method

$
0
0
Most commonly, when we need to log something via a Java logger, we write something like this:

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

Check out the part of the code that is highlighted in red. Well, that part tell us that the above line of code is dependent of the class name where it appears, and this may rise refactoring issues. Moreover, this line must appear in each class that want to use the logger, which is a little bit verbose.

But, CDI comes with a very handy and bidder feature that consist in the fact that we can easily obtained information about the injection point of an artifact. For example, an instance of InjectionPoint can access metadata of the class where the artifact is injected. A bean without an explicit scope (so, having the @Dependent default scope) can inject an instance of InjectionPoint. CDI will take care of providing this instance for us, so all we need to do is to exploit its methods.

Now, if we take a look at the logger case, we can  easily conclude that the logger is dependent of a metadata, or more exactly is dependent on the class name. So, if we write something like below, we can actually obtain the desired metadata in an @Dependent bean:

public class MyLogger {

 @Produces
 Logger produceLogger(InjectionPoint injectionPoint) {

  // get the field injection (e.g. fooLog, buzzLog, bizzLog)      
  Member field = injectionPoint.getMember();
  System.out.println("Member: " + field);

  // get the class containing the field injection
  Class<?> fieldClass = field.getDeclaringClass();
  System.out.println("Class: " + fieldClass);

  // get the class name
  String className = fieldClass.getName();
  System.out.println("Class name: " + className);

  return Logger.getLogger(className);

  // or shortly:
  return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
 }
}

First, we declare the produceLogger()method as a CDI producer method via the @Produces annotation, highlighted in blue. By making this method a producer method, we allow the return value of the method -in this case a Logger- to be injected.

As you can see, the part highlighted in red is responsible to use the instance of InjectionPoint for extracting the name of the class where the artifact is injected. Further, we use the extracted class name to create a logger for that class and return it.

So, now we can simply use a logger via injection. For example, we can inject it in FooBean:

@Named
@RequestScoped
public class FooBean {

 @Inject
 Logger fooLog;

 public void logFooAction() {
  fooLog.info("Log message from FooBean !");
 }
}

Or, in BuzzBean:

@Named
@RequestScoped
public class BuzzBean {

 @Inject
 Logger buzzLog;

 public void logBuzzAction() {
  buzzLog.info("Log message from BuzzBean !");
 }
}

Or, in BizzBean:

@Named
@RequestScoped
public class BizzBean {

 @Inject
 Logger bizzLog;

 public void logBizzAction() {
  bizzLog.info("Log message from BizzBean !");
 }
}

Or, in ... any other bean.

Well, a possible output will be:


The complete example is available here.

CDI-JSF: Injecting HTTP parameters via a producer method

$
0
0
Remeber from the Inject a Java logger via a CDI producer method post that the InjectionPoint can be used to access metadata of the class where the artifact is injected. Based on this statement, we can write a producer method capable to inject HTTP parameters.

Typically, as a JSF developer you write a form like below:

<h:form>
 Name: <h:inputText value="#{playerBean.name}"/>
 Surname: <h:inputText value="#{playerBean.surname}"/>
 <h:commandButton value="Register" action="#{playerBean.registerAction()}"/>
</h:form>

The two fields, nameand surname are declared in a bean privateand with some getters and setters:

@Named
@RequestScoped
public class PlayerBean {

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

 private String name;
 private String surname;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getSurname() {
  return surname;
 }

 public void setSurname(String surname) {
  this.surname = surname;
 }

 public void registerAction() {
  LOG.info("Register: " + name + "" + surname);
 }
}

Well, nothing fancy here, and even a JSF novice can understand what this code do just by looking over it in a second. But, now let's replace the <h:inputText/>with simple HTML <input/>as below:

<h:form>
 Name: <input type="text" name="name" id="name"/>
 Surname: <input type="text" name="surname" id="surname"/>
 <h:commandButton value="Register" action="#{playerBean.registerAction()}"/>
</h:form>

This time our getters and setters become useless, but we can still obtain these two HTTP parameters like this:

FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
ServletRequest request = (ServletRequest) externalContext.getRequest();

request.getParameter("name");
request.getParameter("surname");

Now, let's generalize this  case in CDI style. Instead of writing request.getParameter("name"); we want to inject the HTTP parameter. For this, we start by defining a qualifier and instruct the container to ignore the value:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface HttpParam {
 @Nonbinding public String value();
}

Furthermore, we write the producer method as below - instead of explicitly nominated the HTTP parameter name, we use the InjectionPoint metadata features:

public class HttpParams {

 @Produces
 @HttpParam("")
 String getParamValue(InjectionPoint ip) {

  // obtain the current request
  FacesContext facesContext = FacesContext.getCurrentInstance();
  ExternalContext externalContext = facesContext.getExternalContext();
  ServletRequest request = (ServletRequest) externalContext.getRequest();

  // obtain the desired parameter
  Annotated annotated = ip.getAnnotated();
  HttpParam httpParam = annotated.getAnnotation(HttpParam.class);

  return request.getParameter(httpParam.value());
 }
}

Finally, we adjust the PlayerBeanto inject the desired HTTP parameters:

@Named
@RequestScoped
public class PlayerBean {

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

 @HttpParam("name") @Inject String name;
 @HttpParam("surname") @Inject String surname;

 public void registerAction() {
  LOG.log(Level.INFO, "Register: {0} {1}", new Object[]{name, surname});
 }
}

Done! Following this example you can inject any other HTTP parameter. The complete example is available here.

Now, you can use this with <f:param/> or in place of <f:event type="preRenderView/> or <f:viewAction/>. In addition, you may be interested in converting and validating the HTTP parameters. Check out a great implementation from OmniFaces which is materialized in the CDI annotation @Param that allows us to inject, convert and validate a HTTP request parameter in a CDI managed bean. 

CDI-JSF: Using the CDI @Observes

$
0
0
In this post we will discuss about using the CDI @Observes in a JSF application.

Basically, we will exploit the fact that Java EE provides an easier implementation of the observer design pattern via the @Observes annotation and javax.enterprise.event.Event<T> interface.

Note In the bellow examples, we will use CDI managed beans, but you can use EJB 3 beans also.

Basically, the observer pattern is based on a subject and some observers:

subject - an object that changes its state
observers - objects notified when the subject has changed its state

This time, the subject is a CDI managed bean named, MainFireStationBean:

@Named
@RequestScoped
public class MainFireStationBean {

 @Inject
 Event<String> evt;

 public void fireStarted(String address) {
  evt.fire(address);
 }
}

The container injects an Event object of type String into the evt instance variable of the MainFireStationBean class (practically, this String represents the fire address). To activate an event, call the javax.enterprise.event.Event.fire() method. This method fires an event and notifies any observer methods (observers). Now the observable part is completed, so it is time to create the observers that listens for our String events.

In Java EE the observers are marked with the @Observes annotation. The addition of the @Observes annotation to the method signature instructs the container that this method should act as an observer of events of the type it precedes.

We have three observers, ViningsFireStationBean BrookhavenFireStationBean and DecaturFireStationBean:

@Named
@Dependent
public class ViningsFireStationBean {

 public void update(@Observes String arg) {
  System.out.println("Vinings fire department will go to " + arg);
 }
}

@Named
@Dependent
public class BrookhavenFireStationBean {

 public void update(@Observes String arg) {
  System.out.println("Brookhaven fire department will go to " + arg);
 }
}

@Named
@Dependent
public class DecaturFireStationBean {

 public void update(@Observes String arg) {
  System.out.println("Decatur fire department will go to " + arg);
 }
}

So, the @Observes annotation precedes the type String and thus listens for events of that type. The @Observes annotation followed by an object type instruct the container will all the needed information.

In order to test it, we just need to report some fires. We can do this in several ways, but let's do it quickly via two JSF buttons:

<h:form>
 <h:commandButton value="Report Fire at Home Park Atlanta" 
                  action="#{mainFireStationBean.fireStarted('Home Park Atlanta, GA')}"/>
 <h:commandButton value="Report Fire at High Museum of Art" 
                  action="#{mainFireStationBean.fireStarted('High Museum of Art 1280 Peachtree St NE Atlanta, GA 30309')}"/>
</h:form>

If we suppose that the Report Fire at Home Park Atlanta button was pressed then the output will be:

Decatur fire department will go to Home Park Atlanta, GA
Vinings fire department will go to Home Park Atlanta, GA
Brookhaven fire department will go to Home Park Atlanta, GA

So, everything works as expected. The complete example is available here.

One step further and we will want to differentiate between the same object types of objects and set up different observers to listen for them. For example, we may need to distinguish between small fires and big fires. Depending on this aspect, a local fire station may send to the fire address one fire truck or multiple fire trucks. We can model this case via a qualifier:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
public @interface FireType {

 Type value();

 enum Type {
      SMALL, BIG
 }
}

The two enum types (SMALL and BIG)  will be used to act as annotation to mark the strings to be fired by the event instances. So, the MainFireStationBean will be:

@Named
@RequestScoped
public class MainFireStationBean {

 @Inject
 @FireType(Type.SMALL)
 Event<String> small;

 @Inject
 @FireType(Type.BIG)
 Event<String> big;

 public void fireStarted(String address, boolean t) {
  if (t) {
      small.fire(address);
  } else {
      big.fire(address);
  }
 }
}

Finally, add the annotations to the observer part:

@Named
@Dependent
public class ViningsFireStationBean {

 public void updateSmallFire(@Observes @FireType(FireType.Type.SMALL) String arg) {
  System.out.println("Vinings fire department will go to a small fire at " + arg);
 }

 public void updateBigFire(@Observes @FireType(FireType.Type.BIG) String arg) {
  System.out.println("Vinings fire department will go to a big fire at " + arg);
 }
}

@Named
@Dependent
public class BrookhavenFireStationBean {

 public void updateSmallFire(@Observes @FireType(FireType.Type.SMALL) String arg) {
  System.out.println("Brookhaven fire department will go to a small fire at " + arg);
 }

 public void updateBigFire(@Observes @FireType(FireType.Type.BIG) String arg) {
  System.out.println("Brookhaven fire department will go to a big fire at " + arg);
 }
}

@Named
@Dependent
public class DecaturFireStationBean {

 public void updateSmallFire(@Observes @FireType(FireType.Type.SMALL) String arg) {
  System.out.println("Decatur fire department will go to a small fire at " + arg);
 }

 public void updateBigFire(@Observes @FireType(FireType.Type.BIG) String arg) {
  System.out.println("Decatur fire department will go to a big fire at " + arg);
 }
}

Now, let's report a big fire and a small fire:

<h:form>
 <h:commandButton value="Report a Small Fire at Home Park Atlanta" 
                  action="#{mainFireStationBean.fireStarted('Home Park Atlanta, GA', true)}"/>
 <h:commandButton value="Report a Big Fire at High Museum of Art" 
                  action="#{mainFireStationBean.fireStarted('High Museum of Art 1280 Peachtree St NE Atlanta, GA 30309', false)}"/>
</h:form>

In case of a small fire the output will be:

Brookhaven fire department will go to a small fire at Home Park Atlanta, GA
Vinings fire department will go to a small fire at Home Park Atlanta, GA
Decatur fire department will go to a small fire at Home Park Atlanta, GA

Note that in case of your own object types you don't need qualifiers. Since the object type is unique, you can fire/observe your own object types by using the object.

The complete example is available here.

CDI-JSF: Testing CDI code using CDI-Unit

$
0
0
There are a few approaches to test CDI code such as using @Alternativeand/or mocking. Another approach, presented here is to use the JGlue project - more exactly the CDI-Unit which is a JUnit4 test runner that enables unit testing Java CDI applications.

For example, let's consider the application from post Inject a Java logger via a CDI producer method - in this application you saw exactly what the name of the post say, how to inject a Java logger via a producer method. Now, let's suppose that we want to write a JUnit test for  the method FooBean#logBuzzAction():

@Named
@RequestScoped
public class FooBean {

 @Inject
 Logger fooLog;

 public void logFooAction() {
  fooLog.info("Log message from FooBean !");
 }
}

In a pretty dummy approach we can try this:

public class LoggerTest {

 @Inject
 FooBean fooBean;

 @Test
 public void testStart() {
  fooBean.logFooAction();
 }
}

Well, obviously this will not work! The problem will be caused by the @Injectpart, so is time to find a solution. Add quickly the CDI-Unit dependency in the POM:

<dependency>
 <groupId>org.jglue.cdi-unit</groupId>
 <artifactId>cdi-unit</artifactId>
 <version>3.1.2</version>
 <scope>test</scope>
</dependency>

And specify @RunWith(CdiRunner.class) on your JUnit4 test class to enable injection directly into the test class:

@RunWith(CdiRunner.class)
public class LoggerTest {

 @Inject
 FooBean fooBean;

 @Test
 public void testStart() {
  fooBean.logFooAction();
 }
}

Ok, the FooBean is injected now! But, now we have an unsatisfied dependencies for type Logger.  In order to fix this issue, simply specify MyLoggerclass as an additional class for this test. This will tell  CDI-Unit to explicitly add a class to the CDI environment:

@RunWith(CdiRunner.class)
@AdditionalClasses(MyLogger.class)
public class LoggerTest {

 @Inject
 FooBean fooBean;

 @Test 
 public void testStart() {
  fooBean.logFooAction();
 }
}

Ok, the last issue that we must solve consist in the fact that there is no active contexts for the request scope, but CDI-Unit has built in support for request, session and conversation scopes using @InRequestScope, @InSessionScopeand @InConversationScope. So, let's bring the context in:

@RunWith(CdiRunner.class)
@AdditionalClasses(MyLogger.class)
public class LoggerTest {

 @Inject
 FooBean fooBean;

 @Test
 @InRequestScope
 public void testStart() {
  fooBean.logFooAction();
 }
}

Done! Now the test is ready and you can see it here.

CDI-JSF: Use a CDI alternative as a mock implementation for a stateless session bean

$
0
0
A great feature of CDI (supported by Java EE starting with version 6) consist in alternatives. Basically, we want to specify an alternative for an injected object. Let's have a simple scenario commonly followed in JSF applications that uses stateless session beans to interact with a database. Supposing that we write the business logic part to query the database. We can start with an interface as:

public interface IFooService {
 List getAllFoo();
}

Further, we can write a stateless session bean that implements this interface and take usage of JPA capabilities to query the database. Well the things didn't go too far for this part because the database is not ready and all we can provide is a skeleton like below:

@Stateless
public class FooService implements IFooService {
   
 @PersistenceContext(unitName = "fooPU")
 private EntityManager em;

 @Override
 public List getAllFoo() {
  // perform the query
  ...
  return new ArrayList();
 }
}

Finally, we inject the stateless session bean in a CDI managed bean as below:

Named
@RequestScoped
public class FooBean {

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

 @Inject
 private IFooService fooService;

 public void loadAllFoo() {
  List allfoo = fooService.getAllFoo();
  LOG.log(Level.INFO, "allfoo:{0}", allfoo);
 }
}

Now, let's suppose that we want to run/test this method, but we have an issue. The data that we expect from the database will not be available, so we think to mock this service and provide a set of dummy data as below:

@Stateless
public class FooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("foo 1", "foo 2", "foo 3");
 }
}

But, if we test the code now, we will obtain an error of type ambiguous dependencies. In order to fix this error, we simply annotated our mock with @Alternative annotation:

@Alternative
@Stateless
public class FooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("foo 1", "foo 2", "foo 3");
 }
}

If we run now, there will be no errors, but the application will not use the mock. This is happening because our alternative is not activated. We must accomplish this in the beans.xml, as below:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="all">
   
 <alternatives>
  <class>beans.FooServiceMock</class>
 </alternatives>
</beans>

Done! Now the FooBean will use the FooServiceMockinstead of FooService. When the database will be ready/queryable we will simply deactivate the alternative.

Via CDI-Unit we can write a quick test that also uses our mock:

@RunWith(CdiRunner.class)
@ActivatedAlternatives(FooServiceMock.class)
public class FooBeanTest {
   
 @Inject
 FooBean fooBean;

 @Test
 @InRequestScope
 public void testStart() {
  fooBean.loadAllFoo();
 }   
}

The complete example is available here.

CDI-JSF: Using CDI alternatives priority (@Priority)

$
0
0

So, since you are familiar with the above post, now let's suppose that we have multiple mock implementations. In such cases, the problem is how to instruct the container to choose between the implementations? The answer relies on alternatives priority!

Basically, we annotate each mock implementation with @Priority and provide a number as the level of priority. The higher number has the higher priority. Here it is three mock implementations with priorities 1,2 and 3:

@Priority(1)
@Alternative
@Stateless
public class FooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("foo 1", "foo 2", "foo 3");
 }
}

@Priority(2)
@Alternative
@Stateless
public class BestFooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("best foo 1", "best foo 2", "best foo 3");
 }
}

@Priority(3)
@Alternative
@Stateless
public class GreatFooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("great foo 1", "great foo 2", "great foo 3");
 }
}

The mock implementation annotated with @Priority(3) has the higher priority. When we run the below code CDI will automatically choose the GreatFooServiceMock:

@Named
@RequestScoped
public class FooBean {

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

 @Inject
 private IFooService fooService; // choose GreatFooServiceMock

 public void loadAllFoo() {
  List allfoo = fooService.getAllFoo();

  LOG.log(Level.INFO, "allfoo:{0}", allfoo);
 }
}

Now, we can also write a test using CDI-Unit as below (this will also choose the GreatFooServiceMock):

@RunWith(CdiRunner.class)
@ActivatedAlternatives({FooServiceMock.class, BestFooServiceMock.class, GreatFooServiceMock.class})
public class FooBeanTest {
   
 @Inject
 FooBean fooBean;

 @Test
 @InRequestScope
 public void testStart() {
  fooBean.loadAllFoo();
 }   
}

We can use the @Priority annotation to specify alternatives globally for an application that consists of multiple modules like this:

@Alternative
@Priority(Interceptor.Priority.APPLICATION+10)
public class ...

The complete example is available here.

JSF 2.3 Auto detect Converter based on 1st UISelectMany item

$
0
0
Starting with JSF 2.3, more exactly with m07, we can take advantage of using the auto detection of convertors based on 1st UISelectMany item.The story behind the issue solved in JSF 2.3 is easy to understand via two examples. 

Example 1:

Let's suppose the following code:

<h:form>          
 <h:selectManyListbox value="#{playerBean.selectedRanks}" converter="javax.faces.Integer">               
  <f:selectItems value="#{playerBean.playersRanks}"/>
 </h:selectManyListbox>
 <h:commandButton value="Select" action="#{playerBean.selectedAction()}"/>
</h:form> 

Let's start by supposing that the above built-in converter is not specified. Basically, the playersRanks is a list of integers that "populates" our list, and the selectedRanks represents the user selections:

private ArrayList<Integer> selectedRanks;
private static final ArrayList<Integer> playersRanks;

static {
 playersRanks = new ArrayList<>();
 playersRanks.add(1);
 playersRanks.add(2);
 playersRanks.add(3);
}

public ArrayList<Integer> getPlayersRanks() {
 return playersRanks;
}

public ArrayList<Integer> getSelectedRanks() {
 return selectedRanks;
}

public void setSelectedRanks(ArrayList<Integer> selectedRanks) {
 this.selectedRanks = selectedRanks;
}

So, the user may select the ranks and submit them without issues/errors. Even if no error occurred, we can notice a "strange" behavior if we try to run the following snippet of code:

<ui:repeat value="#{playerBean.selectedRanks}" var="i">
 #{i}: #{i.getClass()}
</ui:repeat>

The output reveals that the selected ranks are strings, not integers as we expected to see:

1: class java.lang.String
3: class java.lang.String

The explanation relies on the fact that "the generic type information of List<Integer> is lost during runtime and therefore JSF/EL who sees only List is not able to identify that the generic type is Integer and assumes it to be default String (as that's the default type of the underlying HttpServletRequest#getParameter()call during apply request values phase) - BalusC".

There are two approaches:
·         explicitly specify a Converter
·         use Integer[] instead

In this case, we can use the built-in javax.faces.Integer built-in converter. Now, we can perform the same test and the output will be:

1: class java.lang.Integer
3: class java.lang.Integer

Example 2:

This use case continue the story from the above use case. Cosider this code:

<h:form>          
 <h:selectManyListbox value="#{playerBean.selectedPlayersList}" converter="playerConverter">               
  <f:selectItems value="#{playerBean.playersList}" var="t" itemLabel="#{t.label}" itemValue="#{t}"/>
 </h:selectManyListbox>
 <h:commandButton value="Select" action="#{playerBean.selectedAction()}"/>
</h:form>

Basically, this time we use data for which we don't have a built-in converter available. The custom converter used here is needed because this time the list is "populated" with several Player instances:

private ArrayList<Player> selectedPlayersList;
private static final ArrayList<Player> playersList;

static {
 playersList = new ArrayList<>();
 playersList.add(new Player("Rafa", "Rafael Nadal"));
 playersList.add(new Player("Roger F", "Roger Federer"));
 playersList.add(new Player("Nole", "Novak Djokovic"));
}

public ArrayList<Player> getPlayersList() {
 return playersList;
}

public ArrayList<Player> getSelectedPlayersList() {
 return selectedPlayersList;
}

public void setSelectedPlayersList(ArrayList<Player> selectedPlayersList) {
 this.selectedPlayersList = selectedPlayersList;
}

// Player class snippet of code 
public class Player implements Serializable {
   
 private String label;
 private String value;

 public Player(String label, String value) {
  this.label = label;
  this.value = value;
 }
 ...

Remember from the above use case that the generic type of List<> is lost during runtime. Since the selected items are treated as strings instead of Player instances, the below code will cause an error because #{i.label} cannot be evaluated:

<ui:repeat value="#{playerBean.selectedPlayersList}" var="i">
 #{i.label}: #{i.getClass()}
</ui:repeat>

Since there is no built-in converter for converting strings to Player instances, we need a custom converter as below:

@FacesConverter("playerConverter")
public class PlayerConverter implements Converter {

 @Override
 public Object getAsObject(FacesContext context, UIComponent component,String value) {
  String[] parts = value.split("/");
  return new Player(parts[0],parts[1]);
 }

 @Override
 public String getAsString(FacesContext context, UIComponent component,Object value) {
  return value.toString();
 }   
}

Now, everything works as expected!

JSF 2.3
Well, while example 1 is pretty simple to "fix", the second example is not so easy since it requires us to write a custom converter. But, JSF 2.3 comes with a new feature that is capable to detect Converter based on 1st UISelectMany item and save us for using a built-in converter or writing a custom one for this purpose. So, in JSF 2.3 the below two codes will work as expected:

1: there is no need to specify a built-in conveter
<h:form>          
 <h:selectManyListbox value="#{playerBean.selectedRanks}" converter="javax.faces.Integer">               
  <f:selectItems value="#{playerBean.playersRanks}"/>
 </h:selectManyListbox>
 <h:commandButton value="Select" action="#{playerBean.selectedAction()}"/>
</h:form> 

<ui:repeat value="#{playerBean.selectedRanks}" var="i">
 #{i}: #{i.getClass()}
</ui:repeat>

2: there is no need to write/specify a custom converter
<h:form>          
 <h:selectManyListbox value="#{playerBean.selectedPlayersList}" converter="playerConverter">               
  <f:selectItems value="#{playerBean.playersList}" var="t" itemLabel="#{t.label}" itemValue="#{t}"/>
 </h:selectManyListbox>
 <h:commandButton value="Select" action="#{playerBean.selectedAction()}"/>
</h:form>

<ui:repeat value="#{playerBean.selectedPlayersList}" var="i">
 #{i.label}: #{i.getClass()}
</ui:repeat>

For studying the implementation please download Mojarra source code and check out the javax.faces.component.UISelectMany, com.sun.faces.renderkit.html_basic.MenuRenderer (especially,  MenuRenderer#getConverterForSelectManyValues()method) and com.sun.faces.util.getConverterForClass().

[OmniFaces utilities 2.4] Check if the given object is serializable

$
0
0

[OmniFaces utilities] The isSerializable() method returns true if the given object is serializable.

Method:
Usage:

Example 1 - test Object:

import org.omnifaces.util.Utils;
...
Utils.isSerializable(new Object()); // return false

Example 2 - test two classes

// Serializable class
public class ShopingCart implements Serializable {
 ...    
}

// NOT Serializable class
public class Item {
 ...    
}

Utils.isSerializable(new ShopingCart()); // return true
Utils.isSerializable(new Item()); // return false

JSF 2.3 - Import constants/enums

$
0
0
Let's checkout a common practice for declaring constants in Java using the public static final declaration:

public class Circle {
 private static final float PI = 3.14f;
 private static final String UNIT = " radians";
 ...
}

Also, Java interfaces and enums are very useful in applications (they are part of the Java language ʺbricksʺ):

public interface Car {
 public String MODEL = "Logan";
 public String COUNTRY = "RO";
}

public enum Cars {
 CITROEN, LOGAN, BMW;
}

Now, letʹs suppose that we have these artifacts in a JSF application, as a JSF page author we need to use them in page via EL, as below:

·         Use constants:

#{Circle.PI}
#{Circle.UNIT}

·         Use interfaces and enums:

#{Car.MODEL}

There is no elegant way to say that the above usages will simply not work!

So, now let's consider the following example. First, we define an enum:

public enum PlayerEnum {

 FIRST, SECOND, THIRD;

 public Integer getRank() {
  switch (name()) {
          case "FIRST":
                return 1;
          case "SECOND":
                return 2;
          case "THIRD":
                return 3;
          default:
                return 0;
  }
 }
}

Further, we use this enum in a CDI managed bean:

@Named
@RequestScoped
public class PlayerBean implements Serializable {

 private static final long serialVersionUID = 1L;

 private PlayerEnum selectedPlayerEnum;
 public static final String NAME_C = "Rafael Nadal";

 public PlayerEnum getSelectedPlayerEnum() {
  return selectedPlayerEnum;
 }

 public void setSelectedPlayerEnum(PlayerEnum selectedPlayerEnum) {
  this.selectedPlayerEnum = selectedPlayerEnum;
 }
}

Well, OmniFaces comes with a tag handler named, <o:importConstants/>that is capable to map of all constant field values of the given fully qualified name of a type in the request scope (it works with enums also). This tag handler is detailed in the book Mastering OmniFaces. PrimeFaces also comes with support for import constants and enums. Before PrimeFaces Elite 5.3.8 this support was available in PrimeFaces Extension as <pe:importConstants/>and <pe:importEnum/>.  Afterwards, this support was moved from PrimeFaces extension to PrimeFaces Elite 5.3.8, and is available via <p:importConstants/> and <p:importEnum/>. This tags are detailed in book, PrimeFaces & OmniFaces - Powers Combined.

Starting with JSF 2.3-m07, we can import constants and enums via the  new <f:importConstants/>tag. Check the NAME_Cconstant from above. Well, this constant (and any other constant from PlayerBean) can be accessed via EL once we import them as below (the type attribute is required and its value represents the fully qualified name of the class/interface/enum to import the constant field values for):

<f:importConstants type="javaee8.jsf23.PlayerBean" />

The <f:importConstants/>supports the varattribute also. You can use it to indicate an alias (the name of the request attribute which exposes the mapping of the constants in the request scope), as
below:

<f:importConstants type="javaee8.jsf23.PlayerBean" var="CONSTANTS" />

Now, we can write this:#{CONSTANTS.NAME_C}

The PlayerEnumcan be imported exactly the same:

<f:importConstants type="javaee8.jsf23.PlayerEnum" />

This allows us to loop the enum, as below (returns FIRSTSECONDTHIRD):

<ui:repeat value="#{PlayerEnum.values()}" var="t">
 #{t}
</ui:repeat>

Now, we can nominate the enum constants:

#{PlayerEnum.FIRST} // returns FIRST
#{PlayerEnum.FIRST.rank} // returns 1

We can put all together and provide enum values as dropdown items:

<h:form>
 <h:selectOneMenu value="#{playerBean.selectedPlayerEnum}">
  <f:selectItems value="#{PlayerEnum}" />
  <f:ajax render="@form" />
 </h:selectOneMenu>
 #{playerBean.selectedPlayerEnum}
 [#{playerBean.selectedPlayerEnum == PlayerEnum.FIRST}]
</h:form>

Even more, we can provide the enum values as dropdown items via the var attribute:

<h:form>
 <h:selectOneMenu value="#{playerBean.selectedPlayerEnum}">
  <f:selectItems value="#{PlayerEnum.values()}" var="t" itemLabel="#{t.rank}" itemValue="#{t}" />
  <f:ajax render="@form" />
 </h:selectOneMenu>
 #{playerBean.selectedPlayerEnum}
 [#{playerBean.selectedPlayerEnum == PlayerEnum.FIRST}]
</h:form>

We can glue all the examples above in the below view:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
   
 <f:metadata>
  <f:importConstants type="javaee8.jsf23.PlayerEnum" />
  <f:importConstants type="javaee8.jsf23.PlayerBean" />
  <f:importConstants type="javaee8.jsf23.PlayerBean" var="CONSTANTS" />
 </f:metadata>
 <h:head>
  <title>JSF 2.3 - ImportConstants</title>             
 </h:head>
 <h:body>                  
  <h5>Display the 'NAME_C' constant value</h5>
  <h:outputText value="#{PlayerBean.NAME_C}"/><br/>
  <h:outputText value="#{CONSTANTS.NAME_C}"/><br/>

  <h5>Loop enum values</h5>
  <ui:repeat value="#{PlayerEnum.values()}" var="t">
   #{t}
  </ui:repeat>

  <h5>Providing enum values as dropdown items and test again 'FIRST'</h5>
  <h:form>
   <h:selectOneMenu value="#{playerBean.selectedPlayerEnum}">       
    <f:selectItems value="#{PlayerEnum}" />
    <f:ajax render="@form" />
   </h:selectOneMenu>
   #{playerBean.selectedPlayerEnum}
   [#{playerBean.selectedPlayerEnum == PlayerEnum.FIRST}]
  </h:form>

  <h5>Providing enum values as dropdown items by var  and test again 'FIRST'</h5>
  <h:form>
   <h:selectOneMenu value="#{playerBean.selectedPlayerEnum}">       
    <f:selectItems value="#{PlayerEnum.values()}" var="t" itemLabel="#{t.rank}" itemValue="#{t}" />
    <f:ajax render="@form" />
   </h:selectOneMenu>
   #{playerBean.selectedPlayerEnum}
   [#{playerBean.selectedPlayerEnum == PlayerEnum.FIRST}]
  </h:form>
 </h:body>
</html>

The complete application is available here.

[OmniFaces utilities (2.4)] Create a copy of the array with items in reversed order

$
0
0

[OmniFaces utilities] The reverseArray() function returns a copy of the array with items in reversed order.

Function:
Usage:

Let's suppose that we have the following simple array defined in a bean:

@Named
@RequestScoped
public class MonthsBean {
   
 private String[] months = new String[] {"January", "February", "March", "April", "May", "June", "July", 
   "August", "September", "October", "November", "December"};

 public String[] getMonths() {
  return months;
 }           
}

Now, we can display the array as it was defined and in reverse order as below:

// as it was defined
<ui:repeat value="#{monthsBean.months}" var="item" varStatus="loop">
 #{loop.index + 1} : #{item} #{!loop.last ? ', ' : ''}
</ui:repeat>

Output:
1 : January , 2 : February , 3 : March , 4 : April , 5 : May , 6 : June , 
7 : July , 8 : August , 9 : September , 10 : October , 11 : November , 12 : December

// reversed (xmlns:of="http://omnifaces.org/functions")
<ui:repeat value="#{of:reverseArray(monthsBean.months)}" var="item" varStatus="loop">
 #{loop.index + 1} : #{item} #{!loop.last ? ', ' : ''}
</ui:repeat>

Output:
1 : December , 2 : November , 3 : October , 4 : September , 5 : August , 6 : July , 
7 : June , 8 : May , 9 : April , 10 : March , 11 : February , 12 : January

CDI-JSF: Beans discovery modes

$
0
0
When we write applications that involves CDI we need to activate CDI by adding in our project a file named beans.xml. Usually, this file will look like below:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
 bean-discovery-mode="all">       
</beans>

In this post, we are interested in the part highlighted in red. If you never notice that part before, then this quick post is for you. Let's see what is happening when we have bean-discovery-mode="all", and for this let's consider a simple interface with two implementations, as follows:

public interface IFoo {
 public void fooSlaveAction();
}

@RequestScoped
public class FooImplAnnotated implements IFoo {

 private static final Logger LOG = Logger.getLogger(FooImplAnnotated.class.getName());  
   
 @Override
 public void fooSlaveAction() {
  LOG.info("FooImplAnnotated#fooSlaveAction() invoked ...");
 }   
}

public class FooImplNoAnnotation implements IFoo {

 private static final Logger LOG = Logger.getLogger(FooImplNoAnnotation.class.getName());  
  
 @Override
 public void fooSlaveAction() {
  LOG.info("FooImplNoAnnotation#fooSlaveAction() was invoked ...");
 }   
}

As you can see, the main difference between these two implementations consist in the fact that FooImplAnnotated is annotated with a CDI annotation, @RequestScoped. Well, now let's inject these two implementation in a third CDI bean:

@Named
@RequestScoped
public class FooBean {
   
 // inject the annotated bean
 @Inject
 private FooImplAnnotated fooAnnotated;        
   
 // inject the no-annotation bean
 @Inject
 private FooImplNoAnnotation fooNoAnnotation;
   
 public void fooMasterAction(){
  // call fooSlaveAction() of the annotated bean
  fooAnnotated.fooSlaveAction();
    
  // call fooSlaveAction() of the no annotation bean
  fooNoAnnotation.fooSlaveAction();
 }   
}

If we test this application (for example by calling the fooMasterAction() method  via a simple EL as #{fooBean.fooMasterAction()}), we will get the following messages  in the server log:

FooImplAnnotated#fooSlaveAction() invoked ...
FooImplNoAnnotation#fooSlaveAction() was invoked ...

Ok, this is the effect of using bean-discovery-mode="all"who tells CDI to discover all beans. No, let's alter the beans.xml as switch the value of bean-discovery-mode from all to annotated:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
 bean-discovery-mode="annotated">       
</beans>

This time the test will fail with an error of type org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type FooImplNoAnnotation with qualifiers @Default. Well, the problem is that the FooImplNoAnnotation is not discoverable and it cannot be injected in FooBean. Since we are looking only for annotated implementation, we can re-write our FooBean like below:

@Named
@RequestScoped
public class FooBean {

 // inject the annotated bean
 @Inject
 private IFoo fooAnnotated;

 public void fooMasterAction() {
  // call fooSlaveAction() of the annotated bean
  fooAnnotated.fooSlaveAction();
 }
}

Now, the test will pass again, and the server log will reveal this message: FooImplAnnotated#fooSlaveAction() invoked ...Since the FooImplNoAnnotation is not discoverable, CDI has choose  the single available implementation, FooImplAnnotated. Of course, if we make the FooImplNoAnnotation discoverable by adding a CDI annotation to it, then CDI will cause  ambiguous dependencies errors.

Ok, finally, let's switch the value of bean-discovery-mode from annotated to none:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
 bean-discovery-mode="none">       
</beans>

This time the test will not cause any error and no messages will be available in the server log. We just told CDI to not try to discover any bean.

The complete example is available here.

OmniFaces 2.4 is released!

Viewing all 74 articles
Browse latest View live