I have a #RequestScoped bean with a List property.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
private List list;
// getters and setters
}
This property is linked to a datatable:
<ice:dataTable value="#{myBean.list}" ..other stuff.. />
The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.
Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.
Any ideas?
Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.
Update 2: I think probably found the problem. My backing beans are annotated with #Controller from Spring. I use this annotation because then use #Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.
You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's #Controller, all bean management related annotations of other frameworks like JSF's #ManagedBean and CDI's #Named are ignored.
I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring #Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.
#Controller
#Scope("request")
public class MyBean implements Serializable {
// ...
}
Alternatively, you can also get rid of Spring #Controller annotation and stick to JSF #ManagedBean. You can use #ManagedProperty instead of #Autowired to inject another #ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard #EJB to inject an #Stateless or #Stateful instance.
E.g.
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
#EJB
private SomeService service;
// ...
}
See also:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?
Related
I am creating new JSF 2.2 application and found this issue:
I have:
1) EL Resolver
<application>
<locale-config>
<default-locale>ru</default-locale>
</locale-config>
<resource-bundle>
<base-name>i18n.messages</base-name>
<var>msg</var>
</resource-bundle>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
<!--<variable-resolver>org.springframework.web.jsf.WebApplicationContextVariableResolver</variable-resolver>-->
</application>
2) Faces Bean
#Named("SubscriberBalance")
#RequestScoped
public class SubscriberBalance extends AbstractManagedBean {
private static final long serialVersionUID = -7018658511320101002L;
private SupportService supportService;
private SubscriberBalanceWrapper subscriberBalance;
private Long subscriberId;
private Integer subscriberType;
private Integer months;
3) Spring4+Hibernate4
And after that,my bean shares data between all users. It behaves like spring singleton. It seems like it ignore JSF scopes and process only Spring scopes. So #Scope("request") is working, but #RequestScope doesnt. How to do it correctly? And why it happening? Thank you
I think I figured out this issue and may be it will be helpful for someone.
So we have:
1) CDI - feature of Java EE 6
2) Spring framework
3) JSF
First of all, Spring never interact with CDI in my case. CDI #Named annotation is JSR 330 annotation. But since spring 3.0, Spring also scans those annotations. So that`s why in my case #Named works.
The second, #Named is full equivalent to #Component. So I could use #Component there as well.
#RequestScope and other JSF annotations will not work because its not JSF context, but Spring context. If we need to use JSF context, we need to use #ManagedBean, etc.
#Scope annotation works because its Spring-managed bean, because I have package-scan enabled for my bean.
So approaches are:
1) Use pure JSF with #ManagedBean annotations. I dont prefer this way. Disadvantages are: poor DI integration, much handy work, etc
2) Use CDI. I dont like it as we have Spring
3) Use Spring everywhere. I love this way as it gives me one-way control on all parts of my system. I will not have to think about JSF specific annotations until I really need them.
So in JSF backend bean should be:
#Controller
#Scope(...)
Please see this article
Thank you
I have a #RequestScoped bean with a List property.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
private List list;
// getters and setters
}
This property is linked to a datatable:
<ice:dataTable value="#{myBean.list}" ..other stuff.. />
The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.
Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.
Any ideas?
Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.
Update 2: I think probably found the problem. My backing beans are annotated with #Controller from Spring. I use this annotation because then use #Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.
You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's #Controller, all bean management related annotations of other frameworks like JSF's #ManagedBean and CDI's #Named are ignored.
I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring #Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.
#Controller
#Scope("request")
public class MyBean implements Serializable {
// ...
}
Alternatively, you can also get rid of Spring #Controller annotation and stick to JSF #ManagedBean. You can use #ManagedProperty instead of #Autowired to inject another #ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard #EJB to inject an #Stateless or #Stateful instance.
E.g.
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
#EJB
private SomeService service;
// ...
}
See also:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?
I'm using #Viewscoped beans in a JSF 2.1 project. The strange thing is that when I first get a page the bean is clearly initialized with all the initial parameters. But when I navigate away, to another page, even if I close the browser tab where te app is open the bean does not die. When I go back to the page that use this bean the values are the same that were modified during the utilization of this page. And more, if I open another browser like IE or Chrome, the values are still there too!!
Is behaving like a sessionscoped. Or somekind of inmortal bean , je.
The bean is annotated like this.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#ViewScoped
public class MyBean {
//the rest of the code.
}
Why this is happen? Could be springframework annotation the cause of the problem?
I found the solution. The problem was my spring annotation in the bean. I use #Controller from Spring Framework. This annotation create a Singleton, so my backing bean, even it has #ManagedBean and #ViewScoped, was created only once, and was never destroyed a re-created in every view.
I deleted #Controller and replace #Autowired for #ManagedProperty for the injection and now everything works as expected.
The answer in this a question help to figure out
Define your Bean using this anotations
#ViewScoped
public #Named class MyBean
#PreDestroy works well.
I'm migrating our current solution from JSF 1.2 to JSF 2. As I need to use the new View scope I'm using JSF 2 annotations. That forced me to inject the Spring beans using the JSF #ManagedProperty annotation instead of Spring's #Autowired
Before it was something like this:
#Autowired private OneService oneService
And now it's like:
#ManagedProperty(value="#{oneServiceImpl}")
private OneService oneService
Do you know if is there a way to annotate the managed properties without needing to state their bean name?
Thanks!
No, there isn't. JSF makes use of Expression Language (EL) to determine which class you refer by name. Using a class called ELResolver he takes the String passed, interprets and makes the appropriate reference. The class SpringBeanFacesELResolver provides integration between the two frameworks intercepts the request and passing it to the context of Spring, which handles the dependencies required to provide the ManagedBeans, who then passes it to the JSF's own ELResolver. So JSF needs the name of the bean to know what to inject.
You can still use Spring with JSF 2. Just create a custom Spring scope which can then be used as the view scope for your beans.
#Named #Scope("view")
public class MyBean {
#Inject
private MyManagedProperty oneService;
//...
}
Steal the implementation of the View scope here: http://cagataycivici.wordpress.com/2010/02/17/port-jsf-2-0s-viewscope-to-spring-3-0/
I am trying to #javax.naming.Inject a Spring 3 Bean called WtvrBean into a JSF 2 #FacesConverter.
Both the Bean and the Converter are on the same package. And, in my spring's applicationContext.xml, I am scanning this package:
<context:component-scan base-package="my-package" />
But this is not working. For sure, the JSF 2 internal class that uses the converter is
definitely not in my-package.
For instance, if I remove the #ManagedBean from a JSF 2 ManagedBean, and replace it to #org.springframework.stereotype.Component or #Controller, the WtvrBean can be #Injected on this ManagedBean, by using Spring WebFlow.
Well, as far as I know, there is no such thing as a #Converter stereotype in Spring.
I know I can use
FacesContextUtils.getWebApplicationContext(context).getBean("WtvrBean")
But, with that approach, the coupling between the web app and the spring is getting more tight. (annotations are metadata, and are not even considered dependency by some authors).
I am using FacesContextUtils so far, if there is no better solution.
Any ideas?
If you want to inject beans into instances of a class, these instances have to be spring-managed. I.e. spring has to instantiate them. And this is not happening, so - no, you can't inject there.
But this is because you register the converter within jsf. You can skip that:
#Component("myConverter")
public class MyConverter implements Converter { .. }
And then, if you are using the spring <el-resolver>:
converter="#{myConverter}"
So that will do it. It has worked for me.
(A workaround worth mentioning is that you can do it by using aspectj weaving and #Configurable, but I'd prefer your FacesContextUtils approach. The weaving modifies classes so that they become spring managed even if they are not instantiated by spring.)
#FacesConverter(value = "examTypeConverter")
#Named
Simple answer.
hey i was facing the same problem that spring beans are not getting injected in the JSF Converter.
then by googling about it i found the answers that after JSF 2.2 we can make converters as jsf managed bean. and then we can inject the spring dependency.
it solved my problem.
#ManagedBean
#RequestScoped
public class CustomerByName implements Converter {
#ManagedProperty(value = "#{customerDao}")
private CustomerDao customerDao;
and in your jsf page use it like a managed bean
converter="#{customerByName}"
Add #Scope annotation (eg with "request" parameter) to your managed bean.
#ManagedBean
#Scope("request")
public class MyBean {
....
}