CDI missing #ViewScoped and #FlashScoped - java

Why is Java EE 6 CDI missing the #ViewScoped and #FlashScoped annotations? (especially the former makes me wonder, because CDI stems from the Seam world, which already knew the very similar ScopeType.PAGE...)
What are the recommended workarounds when using CDI? Use Seam 3?
Thanks

The #ViewScoped is specific to the MVC framework JSF, not to the dependency injection framework CDI. The view scope lives as long as you're interacting with the same JSF view. CDI has not really a notion of "views". The CDI alternative to that is #ConversationScoped which lives longer than the request scope, but shorter than the session scope. You only have to control the termination yourself. You can if necessary use MyFaces CODI to bridge the JSF #ViewScoped to CDI #Named beans. The upcoming JSF 2.2 will have a CDI compatible #ViewScoped in the javax.faces.view package.
The #FlashScoped doesn't exist in JSF. The JSF flash scope exist of basically a map which is backed by a short-living cookie which survives HTTP redirects. You cannot let JSF put managed beans in this scope. You've to manually put/get the values in/from the map yourself and/or use the #{flash} reference in EL which basically refrences the map. Seam Faces has however hijacked the JSF specific javax.faces.bean package for its #FlashScoped annotation, but this is definitely not from standard JSF API.
See also:
Add items to List in Request Scoped Bean - contains some concrete examples of CDI alternatives

You can implement the context and use the #NormalScope to create your own CDI Scope witout using any other framework or waiting for the new JEE7
CDI fires an event AfterBeanDiscovery after each bean call
You can use CDI extension to #Observes this event and add your context implementation
In your scope implementation you can :
Use Contextual to get your bean by its name from FacesContext ViewRoot Map and return it after each ajax call back
Use CreationalContext if the bean name from first step is not found to create it in the FacesContext ViewRoot Map
for a more in-depth explanation i recommand this link : http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/

Related

dependency injection in a servlet 3.0 web app?

I'm trying to write a servlet 3.0 web app, just to learn basic servlet handling. Normally i would use spring.
Now I have a servlet which access a DAO which queries the database. Now, what is the best way to instantiate that DAO and use it? My best guess would be to have a private property in the servlet and create an instance of the DAO when the servlet is created.
But, will the servlet be created multiple times?
Is there something similar to springs dependency injection available in servlet 3.0?
EJB 3 dependency injection is extremely simple to use. A single annotation, #EJB, causes the injection of a declared bean. The injection of the SomeDAO bean into a Servlet 3.0 looks like this:
#WebServlet(name="Messenger", urlPatterns={"/Messenger"})
public class Messenger extends HttpServlet {
#EJB
SomeDAO someDAO;
}
The injected SomeDAO bean could be an interface or a no-interface view bean. As long as there is only one implementation of the interface, it will be injected without any ceremony.
javax.servlet API is one of the technologies included in java-ee.
CDI, is the Context and Dependency Injection technology in java-ee
So to answer your question, your use case could be solved by using only CDI and Servlets.
But most of the application servers that supports above (e.g. TomEE, Glassfish webprofiles), will also support EJB (which uses cdi) and JPA. EJB+JPA can be used to implement DAOs.
Arjan Tijms has put together a nice link overview of what is included and happening in the java-ee-7 world

Hold session in stateful EJB 3.1 bean?

I'm working on a Java webapp trying to combine the following technologies:
Java EE 6
CDI
JSF 2
EJB 3.1
Spring Security
I provide CDI-based backing beans (#ViewScoped, #Named) for my JSF pages.
I use #Stateless EJB beans for the actual work to be done.
I only need few session information like jSessionCookie (managed by container), internal username and some other internal IDs. Now, I wonder where to put this session information so that I can access it in the backing beans for JSF, but also provide it to the stateless EJBs? Should I use a #Stateful EJB session bean or should I create CDI-based POJO with #SessionScoped and #Named?
Are there any best practices?
For your particular use case, a stateful session bean would not be a good choice.
Do note that contrary to what people may claim, stateful session beans are surely not something you should generally avoid. However, they are for advanced use cases, for instance when dealing with JPA's extended persistence context.
The reason why stateful session beans would not work here, is that they are not automatically associated with the HTTP session, which seems to be your prime concern. You could add the #SessionScoped annotation to them, but then you could just as well use a regular managed bean. You would not use any of the particular features of a SFSB.
See alo:
Can I use EJB Stateless Bean with CDI to maintain user session?
Using a Stateful Session Bean to track an user's session
Calling a CDI session scoped producer method from an EJB stateless session bean
Contexts and Dependency Injection in Java EE 6
You can inject your stateless EJBs with a session scoped CDI bean, but you have to realize that within the same application your EJB bean would be dependent on the HTTP session then (something you sometimes want to avoid, e.g. if your bean has to be called from other contexts as well).
#Stateful EJB is something I'd try to stay away from. I believe behavior and state are things that should not be mixed.
I would also go for SJuan76's answer and use SessionScoped JSF backing bean.

difference between jsf beans and ejb beans [duplicate]

This question already has answers here:
When is it necessary or convenient to use Spring or EJB3 or all of them together?
(2 answers)
Closed 3 years ago.
I need some clarification. I know how to work with JSF and its corresponding session beans, but i am getting confused with EJB. What is the difference between the beans introduced with EJB and the session beans used with JSF (for ejb i know about the stateless/full session beans and entity beans, entity manager, etc.). What i just dont get is when to use EJB and when to use jsf beans. Aside from the entity beans, both the ejb stateful/less session beans seem similar to the jsf session beans. I've read about injection ejb's into jsf, but why not just use ejb in conjunction with jsf beans? I hope you can understand my confusion. Thank you.
First of all, we need to know about the difference between JSF and EJB beans.
JSF beans are POJO classes which used to read the component value of JSF. There are two type of beans in JSF:
Managed bean is about how a java bean is created and initialized. As you know, JSF uses the Lazy initialization model. It means that the bean in the particular scope is created and initialized not at the moment when the scope is started, but on-demand, i.e. when the bean is first time required.
Backing bean is about the role a particular managed bean plays. This is a role to be a server-side representation of the components located on the page. Usually, the backing beans have a request scope, but it is not a restriction.
EJB Bean is a server-side component that encapsulates the business logic of an application. The business logic is the code that fulfills the purpose of the application.
Mainly, there are three types of session beans:
1.Statefull session bean
2.Stateless session bean
3.Singleton session bean(ejb 3.1)
There is indeed some confusion between the different types of managed beans in Java EE. To add to the confusion, Java EE 6 has introduced a third kind of managed bean: a CDI bean.
In this answer I try to explain the differences and similarities a little: How do CDI and EJB compare? interact?
Briefly said, JSF managed beans mainly don't offer support for transactions, which is something you often need when working with business logic and especially JPA.
Also note that the term session as in session scoped managed beans is a completely different kind of session than the one the term in stateless and statefull session beans refers to.
There is another gread answer on the site where the differences of CDI and EJB are explained. It helps a great deal when you finally grasp the whole picture. Where to use EJB 3.1 and CDI?

How to inject a Spring bean into a Seam context?

I need to inject a Spring bean into a Seam context. Unless I declare the spring bean as a EJB, I cannot get it injected into other seam-managed components. But when I do this, all the spring injected fields are usless cause Seam creates new instances at run-time.
I also tried to add the <seam:component/> element to the spring bean definition and tried to inject it in the container with the #In("beanId") annotation in the target class but I always end up with a NullpointerException...
EDIT:
I read the online articles and did as they say. My spring component is also added to the seam context (I can tell, cause when I define one with the same ID in seam, it complains). Looks like #In is not picking up....
Have you read this chapter? It should tell you exactly what to do.
Raoul,
Although i do not use Seam along with Spring, chapter 15 of Seam In Action books talks about Spring integration. It is free and is updated.
You have said
I also tried to add the element to the spring bean definition and tried to inject it in the container with the #In("beanId")
Seam in Action book says
The EL expression used in the #In annotation, #{tournamentManager}, resolves to an equivalently named bean in the Spring container, courtesy of the delegating variable resolver
Do you have to use #In("#{beanId}") instead of #In("beanId"), do not ?
I have seen
By default, <seam:component/> will create a STATELESS Seam component with class and name provided in the bean definition.
<bean id="someSpringBean" class="SomeSpringBeanClass" scope="prototype">
<seam:component/>
</bean>
And
The scope attribute of <seam:component/> may be used if you wish the Spring bean to be
managed in a particular Seam scope. The Spring bean must be scoped to prototype if the
Seam scope specified is anything other than STATELESS.
Have you done as above ?
I have a project using Seam + Spring and I have to set #In(create=true) when I want to inject a Spring bean into my Seam component otherwise I get a NullPointerException, you should try it.
I got the same problem as yours. I followed strictly the "Chapter 27. Spring Framework integration" in seam ref. document. But my spring bean was never got injected to seam component. And finally, I found out I had the #BypassInterceptors in my seam component. By removing that annotation, my spring bean was successfully injected. Then I realized that, dependency injection is handled by seam BijectionInterceptor. Thus, the #BypassInterceptors will effectively bypass this filter :)

What's the proper way to access an EJB3 Bean from within a Tapestry Page class?

I want to use an EJB3 from within my Tapestry Page class, I can do JNDI lookup for it, but it will me much convenient to use EJB injection or Tapestry IoC. Is that possible?
Of course! You can either contribute your EJBs via Tapestry's IOC container, so you would do the JNDI lookup in your build methods instead of all over your code (see the manual for information).
Or you could wire up your EJBs as Spring beans (see the Spring EJB documentation for details), and use Tapestry-Spring to allow injecting them into your components via #Inject.

Categories

Resources