How can I integrate JSF with REST? - jsf

I have created a REST service for uploading files. Because of various requirements, I cannot integrate that into the JSF lifecycle. Amongst others:
JQuery handles the POST and expects a JSON response which I don't feel good doing from a bean method.
Fileupload plugin does multiple concurrent file POST s, which AFAIK is not possible (by default) JSF behaviour as event's will be queued.
I have a few options in mind, but I would like to be as intrusive as possible. The ones I have examined so far are:
Using JQuery, populate a hidden field with the location of the files and process them in the ActionListener
Same as above, but also call the ActionListener from JQuery
Store data in the session (since I can access it, from my REST service)
Use an #EJB queue service to pass the data to the bean (#Inject' service to bothbeanandREST` service)
Alternatively, is there a way to actually fetch by #ViewScoped bean given that I have the viewstate form field?

Related

How to listen on a stateless POST request and set JSF managed bean properties

I have a Java-EE application that works with JSF (ManagedBean, ManagedProperty, ect ...) and Spring framework. I need to be able to retrieve data via a javascript form sent from an external website. I have opened the rights to authorize the CORS (Cross Origin or Cross Domain).
I would like to know what is the best way to grab an external form with JSF so that it is processed by my ManagedBean.
To make my question more explicit I made a diagram
==============
EDIT
The application works with JSF, I'm looking for a way to retrieve data (from a Javascript form on an external site) in a ManagedBean under JSF. I tried to retrieve this data by creating a Java-EE standard servlet and using the doPost ... methods of HttpServlet. But this solution does not work (this was the subject of my previous question on S.O). Several people told me that in a web application do not mix Java-EE standard and JSF, it is either Servlet or JSF. I made a diagram (above) explaining quickly what I am trying to do.
To recap: I would like to retrieve data from an external website (via a Javascript form) in the ManagedBean of my application.
==============
I've already tried with a standard Java-EE servlet but it's not the right way. Indeed, with a standard servlet I can recover the data from the form but I can not access the ManagedBean. I must therefore have abandoned this hypothesis.
I did not find a similar question about Stackoverflow, If necessary I can give more indications.
Thank you for your help.

Reading property file data from a servlet

I am working on a web application, in which I am reading some configuration data stored in xml file from a Servlet. I want the data read from this servlet available to all the requests coming to this servlet. So inside the init() method of this servlet I am initializing global variable , which will have content read from this xml file so that all the request coming to this servlet will have this data available and don't have to read from the xml file again and again.
My first question is, is this method is better way to share data among request coming only to this servlet. I don't want to share it across all the servlets.
The rule here is just locality: if that data is only used by one single servlet, it should be local to the servlet, meaning as per you proposal:
a member of the servlet class
loaded in the init method of the servlet
But (as your initial post asked), if that data can be updated by another servlet of the same web application, it make sense to move it one step up to a SerletContext attribute. That way:
it can still be initially loaded in the init method of the servlet
it can be changed at any time by any other component of the web application that knows the name of the attribute.
You can imagine plenty of other ways, by using for example custom events and using an observable pattern, or by mapping the servlet to a special (and private) URL that would signal that the xml file must be reloaded, but IMHO, a servlet context attribute is a clean and simple way to allow different servlet to exchange informations.
But beware, you will still need an extra synchronization mechanisme if your web application is intended to be served by more than one single server

CDI event triggered from MDB to update JSF page

Is it possible to fire a CDI event from an MDB? This MDB is monitoring a JMS queue and then a JSF page needs to be updated.
The issue that I'm experiencing is the JSF bean has a scope (was session, but trying request) and the MDB has no scope. The JSF bean contains the controller code (updating the page) and the #Observes annotation on a method parameter. Because the MDB is not in a 'context' and has no scope, the CDI event is never triggered on the JSF Bean.
How is it even possible then to update a JSF page based on a JMS (with MDB) event?
Disclaimer, I'm pretty sure of my what I'm claiming here but not 100%.
You can't do it with just MDB and CDI events. Typically a CDI event reuses the request thread and executes events synchronously after your method was invoked. That means that it's a potential bottleneck even if it worked. The second part is that it will find observers based on the request that spawned it and not find other "users" or whatever.
You can bridge this in several different ways and with several technologies but WebSockets / the Atmosphere framework is usually a solid way to get the message out there. Note that Primefaces Push exists and is based on Atmosphere.
I had a project recently (small) where I needed a plain tomcat and I could not use WebSockets so I brewed up a solution using CDI events.
It works like this:
Instead of using event.fire(new myEvent()) I went for something more transparent, ie I wanted it to show clearly that this event will be broadcasted to all sessions. So instead I created what I called SessionEventDelegator. It has a method called putEvent(Object object) (also other methods when you need Qualifiers). When you want to send events to all sessions you simply inject that and "put" your event. Maybe I should call it load since it will get fired later ;p
Later A JSF PhaseListener calls getEvents() and get all new events since the last time it checked. A timestamp functionality is in place so that you only get new events.
Now simply iterate over found events and use BeanManager.fire to get them out.
Since the PhaseListener will only trigger when the user makes a new request I use p:poll from primefaces ensuring that it polls for new events every third second.
A cleanup algorithm makes sure that events that everyone got is removed from the queue in SessionEventDelegator.
if you want the code let me know. To lazy to paste it if it doesn't sound right to you.
In case that CDI events won't work (I am not convinced about that because spec says that non-contextual objects can't observe events, there is nothing about firing them) but simplest workaround seems to use interceptor. MDBs can have interceptors so just intercept onMessage method and fire event from the interceptor.
Yes, you can fire CDI events from MDBs. The problem is that they're only going to be observed at the application level. If you're using push technology (e.g. Websockets) you can have this ApplicationScoped object receive the event, and then push to the appropriate client based on session id in websockets.
In RichFaces library there's a4j:push component that does exactly what you need. Check out the RichFaces Push section

Managed bean Constructor is not getting fired in page navigation

I am using MyFaces 1.1.14. I have two JSPX pages with JSF components and my managed bean is in request scope. At first page, bean constructor is getting fired and when I submit a form it is fired again. But after my app navigates to the new page, it is not getting fired. The constructor is supposed to be called, right?
The thing is that page is accessing some properties of the bean — those setters get called — no problem with that, but why is the constructor not called? When the page get loaded I need to get data from previous process (i.e from different framework). What is the problem with my understandings?
The navigation does by default not fire a new HTTP request. Instead, a different view is been used as content of the current HTTP response. Only when you navigate with a redirect by appending the <redirect/> entry to the <navigation-case>, then a new HTTP request would be created.
You should totally understand it if you're familiar with RequestDispatcher#forward() concept of the basic Servlet API which JSF is sitting on top of.
See also:
What is the difference between redirect and navigation/forward and when to use what? - Note that the code examples are targeted at JSF 2.x, but the principles apply as good on JSF 1.x.

Is there a way to have a JSF page automatically update a webpage when bean values change?

(Using JEE6) Is it possible to have a webpage automatically update (or listen) to values from within a bean/class and display them on the JSF when these changes happen?
As KayKay mentioned you can implement some sort of polling methodology using javascript to ask the server periodically to send updates if there are any. And unless you use ajax you will have to be content with only complete page refreshes.
JSF as good as it is, sits on top of basic stateless web technology. As such unless you use Ajax or some custom code the server will only respond to a request from the client. Some libraries like icefaces have incorporated a "push" component that allows what you are looking for (from what I understand, this is a fundamental part of icefaxes). That is, to push server side changes to the client.
You have to set up a listener on your end so that your bean will be notified when a value change happens on the server (like in your backing bean which is on the server). When the change happens you can ask say, 'icefaces push' (or another library like primefaces, which you indicate you don't want to use) to send a notice to the client. The client side code (usually ajax/javascript) will process the notice and then send a request for the whole object per normal request response. That is the notice tells the client something it's interested in changed so the client can ask for an update. Aside from the notice, still request/response.
I mention icefaces push because it seems to be the favoured library for this now. But others have this as well. I don't believe the standard JSF 2.0 AJAX libraries have this.
Here are a couple of resources to look at:
(The video is a good start to get the idea of what is going on, then use the rest of the site)
http://www.icesoft.org/demos/icepush-demos.jsf
Older but I think still relevant IBM tutorial on what you want to do, using inventory changes as an example:
http://www.ibm.com/developerworks/web/library/wa-aj-dynamic/index.html
And another stack question related:
Is there a better Ajax Push for JSF 2.0 than Icefaces
Unfortunately it looks like you cannot do this with just JSF, you will have to use one of these libraries or even harder, roll your own push mechanism.
I don't know of a JSF feature to do so. I would simply do some javascript polling, using for example jquery load method to refresh the parts of the page where the values are displayed.
It would help to know what you want to do : refresh the whole page when there is a change, update somes values that are displayed from the start, or add new values to the page.

Resources