2

How to pass results from RESTful service to JSF components? I read many postings, but couldn't find a straightforward method. Using RESTful APIs wherever possible is the main requirement for my application. Performance is also a key as thousands of data elements will be processed in a day. If I can't find a solution in JSF, I might have to switch to another technology..

Therefore, I'm asking in case I'm missing something completely from other postings since I'm new. Here are a couple of simple scenarios.

On a JSF page, there is a datatable (Primefaces Checkbox based selection). The datatable displays records available (up to thousands). The datatable needs to be loaded through a RESTful api on the fly. Below is the code for my datatable.

    <p:dataTable id="addSampleTable" var="sample" value="#{testBean.sampleDataModel}"
            selection="#{testBean.selectedSamples}" >

    <p:column selectionMode="multiple" style="width:2%" /> 
    <p:column headerText="Sample">
        <h:outputText value="#{sample.name}" />
    </p:column>
</p:dataTable>

What's the best way to load the data? Is there a performance concern if every time I have to call the API from the server side (as opposed to client side using jquery and plain html)?

Second scenario, on the same page, there is also a button that allows user to add new record through another RESTful api. In turn, the newly added record should be displayed in the datatable.

After I call the RESTful API to insert a record, the api also returns the record that was created. How can I insert this new record into my datamodel #{testBean.sampleDataModel} so that I don't have to load the entire table again? I suppose I can replace this datatable with plain html and append the new record to the table using jQuery, but then I can't leverage the selection table from JSF.

What are my options?

yisa
  • 51
  • 1
  • 1
  • 5

3 Answers3

4

Your question seems to be too broad, however I try to give some answers.

How to pass results from RESTful service to JSF components?

You can use the pattern implemented by NetBeans' guys. If you use this IDE, there is an option to automatically Build RESTful web services from database. Essentially, this pattern create all DAO basic functionalities in an abstract generic class called AbstractFacade. Then, for each concrete Entity class present in your JPA representation, it creates a Stateless class extending AbstractFacade, and adds jax-rs annotations to it in order to let it expose the Entity class through RESTful web service.

You can then access the service directly by EJB injection. Just use @EJB annotation to inject your service in any container-managed class (in the same application, but also in other applications provided that you use portable JNDI naming rules). In particular, you'll be interested in injecting the facade classes in the managed beans backing your facelets components.

What's the best way to load the data? Is there a performance concern if every time I have to call the API from the server side (as opposed to client side using jquery and plain html)?

Since you need to display thousands of records, your best bet is using Primefaces' lazy loading in your datatable. Your application will then call the db only for retrieving the few tens of records displayed in the current page. Absolutely avoid displaying more than those records, otherwise the client browser will likely be negatively impacted.

How can I insert this new record into my datamodel #{testBean.sampleDataModel} so that I don't have to load the entire table again?

Please distinguish between loading from db and loading in jsf. You can program your backing bean in order to call the db (which is usually the most expensive operation) only when you think it's necessary. As far as I know, both JSF's and PrimeFaces' dataTable implementations don't give you the possibility to manage the table contents at a row level: at every ajax update, the entire table will be reloaded. However, as already said, this won't impact your application's performances as long as you have correctly programmed your backing bean (i.e. choosing the right bean scope and avoid calling the db service in getters).

Useful Links:

perissf
  • 15,979
  • 14
  • 80
  • 117
1

Although this question is a little bit old, it's still a current issue. I'm not happy with the anwsers above because the both technologies mentioned above are together a missmatch.

The most important question here is: Does the given RESTful API actually act as a ...

  • service/buisness layer or ...
  • ... does it provide CRUD operations only? If it only provides typical CRUD operations, it acts as a persistance layer and there is a need for a service layer.

In the second case, you can implement your service layer in a technology of your choice, JSF backed beans or even EJBs are a good choice. In the Java EE context the JAX-RS specification is a good choice, Jersey is an implementation of this specification. You can use this client API to access the RESTful API from Java: [1]

But...

When you design a complete new application, ensure your RESTful api provides not just CRUD operations but also provide higher leven service layer operations (accessed by https POST method) and deal with security concerns.

In this case heterogeneous systems like webapplications, mobile webapps, native mobile apps and so on can access the service layer directly and the particular view (the REST service consumer) is loosly coupled with the service layer (wich is a good thing in software engineering in general).

My opinion: forget old fashioned server side web frameworks like JSF, Struts and so on, provide a RESTful API with service layer operations and use JavaScript frameworks like AngularJS in order to access the RESTful operations directly... mobile apps are the next step. The complete Java EE technology stack is a little bit rusty ;-)

[1] https://jersey.java.net/documentation/latest/user-guide.html#client

kalamar
  • 933
  • 1
  • 11
  • 27
0

What's the best way to load the data? Is there a performance concern if every time I have to call the API from the server side (as opposed to client side using jquery and plain html)?

Yes, there is a performance concern. The best way is to load your collection once into page context and operate on the list in this context. Then once you have done all your changes you synchronize with the stateless REST service.

How can I insert this new record into my datamodel #{testBean.sampleDataModel} so that I don't have to load the entire table again?I suppose I can replace this datatable with plain html and append the new record to the table using jQuery, but then I can't leverage the selection table from JSF.

No, you don't have to do that! There are several JSF datatable implementations which use AJAX partial submit, the datatable code already includes the logic you describe above. Your collection in page scope is extended with the new element without rerendering the whole list again.

Gabor Jakab
  • 236
  • 2
  • 6