JSF and CDI with inputFile component - java

I made a simple xhtml page for upload file by using <h:inputFile> component. And everything works fine. And in managed bean I used dependency injection for the Logger. I used a factory class and createLogger() method in, to enable injection for object of Logger class.
Everything is ok but, nothing works without a #Model annotation in managed bean.
Can somebody explain the meaning of the #Model annotation.
I can not find on internet proper explanation. A founded explanation of other annotation like as #Session, #Request, #Application etc.
What does the #Model annotation do?

Hej vmaric,
#Model == #RequestScoped + #Named
It exposes the Backing Bean directly to your JSF 2 or JSP and its context will be destroyed after the end of the servlet request.
So it should not be used for entities.
Here is a hint from the Weld Reference Guide:
Notice the controller bean is request-scoped and named. Since this combination is so common in web applications, there's a built-in annotation for it in CDI that we could have used as a shorthand. When the (stereotype) annotation #Model is declared on a class, it creates a request-scoped and named bean.

Related

JSF Named Bean, Eager application scoped (aka #ManagedBean(eager=true) )

Is there any way to initialize Named Bean annotaded by javax.inject.Named/javax.enterprise.context.ApplicationScoped like #ManagedBean(eager=true) from javax.faces package?
#Named
#ApplicationScoped
public Mail() { ... }
I want to load this class when application starts, not when webapplication refers to this bean.
ps. JSF 2.1
Bean Injected by Glassfish 3.1
You can create a CDI extension that has the #Observes AfterBeanDiscovery parameter on one of his methods. There you can instantiate the bean and thus initialize it when the container starts up.
CODI has made those things easier for you, see https://cwiki.apache.org/confluence/display/EXTCDI/Core+Usage#CoreUsage-Startup

Inject a Entity into a ViewScoped Bean

I am new to CDI and want to use this for a JSF2 application. The class MyUser is a simple #Entity-Bean and a object is created in a #PostConstruct method in bean:
#Stateful
#Named #javax.faces.bean.SessionScoped
public class UserBean implements Serializable
{
#Named
private MyUser user;
//setter and getter
//#PostConstruct
}
Accessing the user in a JSF pages works like a charm: #{user.lastName}. But now I want to access this object from other beans, e.g. in this #ViewScopedBean:
#Named #javax.faces.bean.ViewScoped
public class TestBean implements Serializable
{
#Inject private MyUser user;
}
I want the current (logged in) MyUser user to be available in a couple of other beans, but I'm not sure how to do this. Simply #Injecting it did not work (and I'm pretty sure this would be a litte bit to simple).
13:56:22,371 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController]
Error installing to Start: name=vfs:///Applications/Development/
jboss-6.0.0.Final/server/default/deploy/test.ear_WeldBootstrapBean state=Create:
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied
dependencies for type [MyUser] with qualifiers [#Default] at injection
point [[field] #Inject private test.controller.mbean.TestBean.user]
What is the best approach to access the user from other beans? JSF1.2 style code like UserBean bean = (UserBean)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("UserBean"); seems seems to be old fashioned!
First of all: You don't want to directly inject entities. Entities are pretty independently controlled by the ORM-framework, and have their own life cycle. Don't use them as managed beans.
According to this definition, JPA
entities are technically managed
beans. However, entities have their
own special lifecycle, state and
identity model and are usually
instantiated by JPA or using new.
Therefore we don't recommend directly
injecting an entity class. We
especially recommend against assigning
a scope other than #Dependent to an
entity class, since JPA is not able to
persist injected CDI proxies.
See here for details.
To answer your question: You cannot "outject" something like an (authenticated) user, even though this was possible in Seam 2, the whole proxy mechanism of CDI doesn't allow this anymore. What you need to do is the following:
Write a managed bean which handles the authentication and put it in the correct scope (probably session scope).
If login succeeds, use an attribute of this bean to store the authenticated user.
Use a producer method (probably with a qualifier like #LoggedIn) to make the user availabe in your application
Inject the user like this:
#Inject
#LoggedIn
private User user
That's the CDI-way ;-)
Is the #Inject ed bean a #Named bean, too?
If it is, has the MyUser bean a lesser scope than the TestBean. Remember that a #ViewScoped bean's managed properties have to be #ViewScoped, #SessionScoped or #ApplicationScoped
CDI does not specify a #ViewScoped annotation. This is a JSF2 annotation. The only possible annotations allowed are : #RequestScoped, #SessionScoped, #ApplicationScoped, #Dependent and #ConversationScoped. The first three are the only JSF scopes allowed by CDI.
If you need to support the #ViewScope annotation, you'll need write it yourself. Luckily, someone else has done this before.

How to get a prototype bean for a singleton Controller in Spring?

I'm using annotation configuration and I currently cannot use request scope for my controller, but I need one of the bean that controller uses to be a prototype. So I figured the best way would be getting prototypes for a singleton controller via method injection.
But then I realized that Spring's method injection needs an abstract class so that I couldn't use my annotation configuration ...
Could please anybody tell me how to do that ? It seems to me that it is very common scenario, but currently it can be realized only via "request scope" of controller.
Or I'd have to make my controller ApplicationContextAware and get the bean from context. But can annotation-config #Controller be ApplicationContextAware ?
You can simply #Inject ApplicationContext ctx, but you need your other bean to be defined in the child context (dispatcher-servlet.xml) (you need that anyway). And then you can look it up.
There is no way to define lookup-method injection with annotations currently. There is an open issue about that. So for this particular controller you can use xml configuration to define the lookup-method.

What is javax.inject.Named annotation supposed to be used for?

I am trying to understand the javax.inject package and I am not clear what the javax.inject.Named annotation is supposed to be used for. The Javadoc does not explain the the idea behind it.
Javadoc is at http://download.oracle.com/javaee/6/api/javax/inject/Named.html
I am using Spring 3.0 to write some sample programs, by putting #Named on a bean it seems to add it to the bean factory but the Javadoc description is so light I can't tell if that is the standard behavior or Spring specific behavior.
My questions are:
What is the difference between #Named and #Qualifier
How are you supposed to tell the Runtime system a class should be injectable in other classes what's the annotation for that? The equivalent of #Component in Spring?
Update 1 there is an excellent explanation of #Named and #Qualifier at Nice article about #Named and #Qualifier https://dzone.com/articles/java-ee6-cdi-named-components thanks #xmedeko for linking to it the comment below.
Use #Named to differentiate between different objects of the same type bound in the same scope.
#Named("maxWaitTime")
public long maxWaitTimeMs;
#Named("minWaitTime")
public long minWaitTimeMs;
Without the #Named qualifier, the injector would not know which long to bind to which variable.
If you want to create annotations that act like #Named, use the #Qualifier annotation when creating them.
If you look at #Named, it is itself annotated with #Qualifier.
#Inject instead of Spring’s #Autowired to inject a bean.
#Named instead of Spring’s #Component to declare a bean.
Those JSR-330 standard annotations are scanned and retrieved the same way as Spring annotation (as long as the following jar is in your classpath)
Regarding #2, according to the JSR-330 spec:
This package provides dependency
injection annotations that enable
portable classes, but it leaves
external dependency configuration up
to the injector implementation.
So it's up to the provider to determine which objects are available for injection. In the case of Spring it is all Spring beans. And any class annotated with JSR-330 annotations are automatically added as Spring beans when using an AnnotationConfigApplicationContext.
The primary role of the #Named annotation is to define a bean for the purpose of resolving EL statements within the application, usually through JSF EL resolvers. Injection can be performed using names but this was not how injection in CDI was meant to work since CDI gives us a much richer way to express injection points and the beans to be injected into them.

How to inject resources into EJB3 beans with Spring 2.5?

If I create an EJB3 bean (say a stateless session bean) in an application using Spring 2.5 for DI, how should I inject dependencies from Spring into the bean without coupling the bean to Spring?
I don't know if you consider applying an interceptor as coupling but that's to my knowledge the standard approach. From the Chapter 18. Enterprise Java Beans (EJB) integration of the documentation:
18.3.2. EJB 3 injection interceptor
For EJB 3 Session Beans and
Message-Driven Beans, Spring provides
a convenient interceptor that resolves
Spring 2.5's #Autowired annotation
in the EJB component class:
org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.
This interceptor can be applied
through an
#Interceptors
annotation in the EJB component class,
or through an interceptor-binding XML
element in the EJB deployment
descriptor.
#Stateless
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class MyFacadeEJB implements MyFacadeLocal {
// automatically injected with a matching Spring bean
#Autowired
private MyComponent myComp;
// for business method, delegate to POJO service impl.
public String myFacadeMethod(...) {
return myComp.myMethod(...);
}
...
}
SpringBeanAutowiringInterceptor by
default obtains target beans from a
ContextSingletonBeanFactoryLocator,
with the context defined in a bean
definition file named
beanRefContext.xml. By default, a
single context definition is expected,
which is obtained by type rather than
by name. However, if you need to
choose between multiple context
definitions, a specific locator key is
required. The locator key (i.e. the
name of the context definition in
beanRefContext.xml) can be
explicitly specified either through
overriding the
getBeanFactoryLocatorKey method in a
custom
SpringBeanAutowiringInterceptor
subclass.
The only other option I'm aware of (extending the EJB 2.x support classes) is much worse from a coupling point of view (and thus doesn't answer your question).
See also
Default Injecting Spring bean to EJB3 SLSB without #Autowired Annotation

Categories