I'm trying to access an object in my sessioncontroller (sessionscoped bean) from a managedbean. The sessionobject gets created when you log in. Then when I try to persist from the requestscoped bean and I need the login-object from the sessioncontroller but when I debug it's always null.
Bean
#ManagedBean
#ViewScoped
// ??? #RequestScoped
public class BoekingController {
#Inject
private ZoekService zoekService;
#Inject
private BetaalwijzeService betaalwijzeService;
#EJB
private transient BoekingService boekingService;
#ManagedProperty("#{sessionController}")
private SessionController sessionController;
public void init() {
if (betaalwijzeId > 0) {
betaalwijze = betaalwijzeService.findToegestandBetaalwijze(betaalwijzeId);
}
reis = zoekService.findReis(reisId);
if (aantalPersonen > 0) {
instellenBoeking(aantalPersonen, betaalwijze, new Klant(1, "Test", "test#test.be", "test"), reis);
}
}
As you can see I have hardcoded the object myself and persistence works, I just can't get the variable from the sessionController posted below.
SessionController
#SessionScoped
#Named(value = "sessionController")
public class SessionController implements Serializable{
Klant klant;
public Klant getKlant() {
return klant;
}
public void setKlant(Klant klant) {
this.klant = klant;
}
On pages I can access the sessionobject by using:#{sessionController.klantNaam}
The annotation ManagedProperty, as explained in the linked javadoc, should be used to inject a JSF bean annotated with ManagedBean.
Use Inject annotation for injecting a CDI bean.
Related
I have Session scope bean which behaves as request scope bean.
I'm using it in Singleton bean, and maybe that's why with second request is has null values?
Code which I used to setup the bean:
In singleton:
#Autowired
private MyBean myBean;
MyBean class:
#Component
#Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public class MyBeanImpl implements MyBean, Serializable {
Configuration:
#Configuration
#ComponentScan(scopedProxy = ScopedProxyMode.INTERFACES, value = { "my.package.with.bean" })
public class ComponentsConfig {
}
MyBean is simple pojo. with getters and setters.
With first request I set values on that bean, with second request in the same class (singleton) I want to read those values, but all values are null. There is no way that something has overrdiden those values.
EDIT
How I make requests - It's just simple browser request, and code which read/writes to my session bean lays in filters.
This is singleton:
#Service
public class SingletonBean {
#Autowired
private MyBean myBean;
// here I save the data to session scoped bean
private void saveUser(LdapContext ctx, String principal) throws NamingException {
Attributes attributes = getAttributes();
myBean.setId("id");
myBean.setName("name");
myBean.setEmail("email");
myBean.setTelNum("123");
myBean.setGroups(Lists.newArrayList("one", "two"));
myBean.setAddress("address");
}
// here I try to read data from session scoped bean:
#Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
// here userInfo will be null
List<String> userInfo = myBean.getGroups();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
for (String role : userInfo ) {
authorizationInfo.addRole(role);
}
return authorizationInfo;
}
}
When user logs in, and he is authenticated, I save his details in session bean. When he tries to open any page method queryForAuthorizationInfo is executed (after chain of filters) and values are null in that object.
i would need to get a viewScoped managed bean from a sessionScoped managed bean. I tried firstly using the #ManagedProperty annotation, but i discovered immediately the it does not work and i know why. Secondly i tried to use the following method:
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
PulsantieraBean pulsantiera = (PulsantieraBean) viewMap.get("#{pulsantiera}");
but when i access in debug to the objects, pulsantiera is null and viewMap object contains only another viewScoped managed bean.
The PulsantieraBean class is declared in the following way:
#ViewScoped
#ManagedBean(name = NomeBean.PULSANTIERA)
public class PulsantieraBean extends ControllerBaseBean implements Serializable {
whereas the class in which i do the request is declared as the following
#SessionScoped
#ManagedBean(name = NomeBean.IDF_TAB_IMPORTI)
public class IdfTabImportiBean extends ControllerBaseBean implements Serializable {
I do the request inside a method in which i am sure the viewScoped managed bean PulsantieraBean exists.
Any help would be appreciated.
Thanks,
Marco
#Named(value = "controladorMB")
#SessionScoped
public class ControladorMB implements Serializable {}
call ControladorMB from ListadoFacturasMB
#Named(value = "listadoFacturasMB")
#SessionScoped
public class ListadoFacturasMB implements Serializable {
public void example() {
try {
FacesContext ctx = FacesContext.getCurrentInstance();
ValueExpression vex =ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(), "#{controladorMB}", ControladorMB.class);
ControladorMB gMB = (ControladorMB) vex.getValue(ctx.getELContext());
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error: buscarPersonalizado() " + e.getMessage());
}
}
}
This is my current scenario:
#WebListener
public class WebListenerService implements HttpSessionListener{
.... implement methods
#Produces
#Dependent
public SessionDependentService sessionDependentService(){
}
}
#SessionScoped
#Named
public class AccountController implements Serializable{
//Injected properly and works as expected
#Inject
private SessionDependnetService sessionDependentService;
#Inject
#OnLogin
private Event<Account> accountEvent;
public void onLogin(){
accountEvent.fire(authenticatedAccount);
}
}
#SessionScoped
public class AccountObserver implements Serializable{
//This does not work. It is always null.
#Inject
private SessionDependnetService sessionDependentService;
public void onLoginEvent(#Observes #OnLogin final Account account) {
//When this methods is invoked
//the sessiondependentservice is always null here.
}
}
In the AccountController, the SessionDependentService is correctly injected and is not null, while in the AccountObserver, it is always null.
EDIT:
Event using the parameter injection still results to a null value.
public void onLoginEvent(#Observes #OnLogin final Account account, final SessionDependnetService sessionDependentService) {
//When this methods is invoked
//the sessiondependentservice is always null here.
}
Netbeans correctly highlights this as an injection point.
Why is this the case?
I am using wildfly 8 server.
I changed the producer bean from SessionScoped to Stateless bean:
#Stateless
public class WebListenerSessionService {
//Use Instance since http session are dynamic.
#Inject
private Instance<HttpSession> httpSession;
#Produces
#Dependent
public SessionDependentService sessionDependentService(){
//use session to lookup existing service or produce a new one.
}
}
Even though this works fine, there is no where in the CDI spec which says Producer method must be session beans.
to quote:
A producer method must be a default-access, public, protected or private, non-abstract method
of a managed bean class or session bean class. A producer method may be either static or non-
static. If the bean is a session bean, the producer method must be either a business method of
the EJB or a static method of the bean class.
And since #SessionScoped is a managed bean class, why would it an injection into an observer bean not work.
Trying to add a functionality to our JSF 2 application to list active users (who have an active session) and for this I decided to use an application scoped managed bean and store the list of users, adding each by the time of a successful login. Then I would access the active user list (stored on the application scoped managed bean) from a jsf page - only if I could figure out how to resolve the following problem:
The application scoped bean : AppBean.java
#ManagedBean(name = "appBean")
#ApplicationScoped
public class AppBean implements java.io.Serializable {
private List<User> connectedUsers = new ArrayList<User>();
public AppBean() {
}
public List<User> getConnectedUsers() {
return connectedUsers;
}
public void setConnectedUsers(List<User> connectedUsers) {
this.connectedUsers = connectedUsers;
}
}
the Login Bean:
#Named(value = "loginBean")
#SessionScoped
public class LoginBean implements Serializable {
#ManagedProperty("#{appBean}")
private AppBean appBean;
private User userInSession;
public LoginBean() {
}
public String authenticate() {
if (this.authClearsOut()) {
if (appBean != null)
appBean.getConnectedUsers().add(userInSession);
else System.out.println("appBean = null !!!!");
return "/next_screen.xhtml?redirect=true";
}
else return "/login.xhtml?authentication=failed";
}
public AppBean getAppBean() {
return appBean;
}
public void setAppBean(AppBean appBean) {
this.appBean = appBean;
}
}
Now there are two problems here:
1) the appBean is null unless I change line 6 of the LoginBean.java to private AppBean appBean = new AppBean();
2) User userinSession is never added to (List) connectedUsers.
What's wrong here?
The JSF #ManagedProperty annotation works in JSF #ManagedBean only, not in CDI #Named.
Change the LoginBean to be managed by JSF #ManagedBean instead, or change the AppBean beans to be managed by CDI #Named and then use #Inject instead of #ManagedProperty.
I have an old project that I need to integrate with Spring 2.5.x (3.0 is not possible).
I have created a bean, that have to initializate its field userSession by itself:
public class SomeBean {
UserSession userSession;
#PostContrust
public void init() {
HttpSession session = WebContext.current().getSession();
userSession = (UserSession) session.getAttribute("userSession");
}
}
Is it possible to write some kind of autowiring handler that will resolve userSession and pass it for autowiring to Spring, so my bean looks just like:
public class SomeBean {
#Autowire UserSession userSession;
}
and the handler like:
public class AutowireHanlder {
public boolean isCandidate(Class<?> type) {
return type.equals(UserSession.class);
}
public Object resolve(Class<?> type) {
HttpSession session = WebContext.current().getSession();
return (UserSession) session.getAttribute("userSession");
}
}
I would do this using a session-scoped FactoryBean:
public class UserSessionFactoryBean extends AbstractFactoryBean<UserSession> {
#Override
public Class<?> getObjectType() {
return UserSession.class;
}
#Override
protected UserSession createInstance() throws Exception {
HttpSession session = WebContext.current().getSession();
return (UserSession) session.getAttribute("userSession");
}
}
Define UserSessionFactoryBean as a bean:
<bean scope="session" class="com.xyz.UserSessionFactoryBean"/>
... and then you should then be able to autowire UserSession into any other bean.
The complexity here is that UserSessionFactoryBean has to be session-scoped (see docs on bean scopes), since it must return a new value for each HttpSession. This means that any bean it is autowired into must also be session-scoped, otherwise it'll fail. You can get around this restriction using scoped-proxies.