With the release of the CDI portlet integration library, we can use the huge advantages brought by CDI through the portlet Bridge in the JSF Portlet.
How to use it?
In addition to the usual Portlet bridge dependency, you also need:
Add the following dependency packages to the project:
<dependency> <groupId>org.gatein</groupId> <artifactId>cdi-portlet-integration</artifactId> <version>1.0.2.Final</version> </dependency> <dependency> <groupId>org.gatein</groupId> <artifactId>cdi-portlet-integration</artifactId> <version>1.0.2.Final</version></dependency>
In the WEB-INF directory of the WAR package, add an empty beans. xml file.
Add the following filter definitions in the portlet. xml file:
filter> <filter-name>PortletCDIFilter</filter-name> <filter-class>org.gatein.cdi.PortletCDIFilter</filter-class> <lifecycle>ACTION_PHASE</lifecycle> <lifecycle>EVENT_PHASE</lifecycle> <lifecycle>RENDER_PHASE</lifecycle> <lifecycle>RESOURCE_PHASE</lifecycle> </filter> <filter-mapping> <filter-name>PortletCDIFilter</filter-name> <portlet-name>yourPortletName</portlet-name> </filter-mapping> <filter> <filter-name>PortletCDIFilter</filter-name> <filter-class>org.gatein.cdi.PortletCDIFilter</filter-class> <lifecycle>ACTION_PHASE</lifecycle> <lifecycle>EVENT_PHASE</lifecycle> <lifecycle>RENDER_PHASE</lifecycle> <lifecycle>RESOURCE_PHASE</lifecycle></filter> <filter-mapping> <filter-name>PortletCDIFilter</filter-name> <portlet-name>yourPortletName</portlet-name></filter-mapping>PortletCIDFilter
Only received portlet requests can use CDI. If your program code framework needs to process the portlet response, you need to use the portletcdireeclipsefilter that can process requests and respond.
@ RequestScoped
The behavior of beans using this scope in the portlet is different from that in the normal JSF. In portelt, the bean class is set as ActionRequest, and any modified content cannot reach other stages of the portlet lifecycle, including RenderRequest. Therefore, we recommend that you do not use this scope in the CDI bean class of the JSF portlet. We recommend that you use the newly added @ PortletLifecycleScoped in 3.6.0 Final. This new scope allows you to set the data you want in an action to render the portlet. In addition, you can maintain the Bean entity from the ActionRequest to the RenderRequest stage.
@ ConversationScoped
A temporary session has the same behavior as a Bean class marked as @ RequestScoped. Therefore, it is not recommended to render the JSF portlet to make the data available.
JSF portlet is expected to provide support for long sessions, but there are still some problems to note:
In the RenderRequest stage, when a long session is ended, a ConversationNotFoundException will appear in the subsequent portlet rendering. This is because the url triggered by portlet rendering contains the cid parameter. CDI determines whether to create a long session or a temporary session based on this parameter. If the parameter still exists at the end of the session, the next time the portlet renders the session, it will try to restart and end the session.
Using AJAX to start or end a long session is a good choice. We need to re-render all the portlet components, including the URL, so that CDI can know the session used by clicking a link or button. If the URL is not updated, the link may be assigned an old cid value, resulting in ConversationNotFoundException, or there is no cid directly, resulting in all calls being temporary sessions.
Latency in Scopes
Recently, mongoin 3.6.0 Final provides two new scopes: @ PortletLifecycleScoped and @ PortletRedisplayScoped. These two scopes are very useful in JSF portlet and can seamlessly interact with bean classes in other CDI scopes. These scopes will be discussed in the blog post of intent in.
I hope this article will point out some common traps when using CDI in JSF portlet development.