I am using jsf 2.0 and I have two bean Navigation (Application Scope ) and Module (Request Scope). I want to use methods of Navigation bean in Module Bean. I am doing in this way
In Module Bean
#ManagedProperty(value = "#{navigationBean}")
private NavigationBean navigationBean;
But when I am trying to get navigationBean.SomeMethod it is not working as navigation bean is null . How to do this?
The both beans needs to be a fullworthy #ManagedBean. The acceptor should have a public setter method for the injected bean. The injected bean is only available in #PostConstruct and beyond (i.e. in all normal event methods, but thus not in the constructor of the acceptor).
So, this ought to work:
#ManagedBean
#ApplicationScoped
public class Navigation {
// ...
}
#ManagedBean
#RequestScoped
public class Module {
#ManagedProperty(value="#{navigation}")
private Navigation navigation;
#PostConstruct
public void init() {
navigation.doSomething();
}
public void setNavigation(Navigation navigation) {
this.navigation = navigation;
}
}
I think #ManagedProperty requires a public set method to work.
I got The solution
I have a method in application signature boolean getReadAccess(String role, String module ). If i want to use in another bean then i have to follow these steps
`javax.el.MethodExpression readAccess;
javax.el.ELContext elContext = null;
javax.faces.context.FacesContext context = FacesContext.getCurrentInstance();
elContext = ((FacesContext) context).getELContext();
javax.faces.application.Application application = FacesContext.getCurrentInstance().getApplication();
javax.el.ExpressionFactory expressionFactory = application.getExpressionFactory();
readAccess = expressionFactory.createMethodExpression(elContext,
"#{navigationBean.getReadAccess}", Void.class, new Class[] {
String.class, String.class });
//--------Call----------------------------
return (Boolean) readAccess.invoke(elContext, new Object[] {
"roleName", "moduleName" });
`
Related
I searched similar questions but I'm a bit confused. I have a login page, so LoginBean also which is;
#ManagedBean(name = "loginBean")
#SessionScoped
public class LoginBean implements Serializable {
private String password="";
private String image="";
#ManagedProperty(value = "#{loginBeanIdentityNr}")
private String identityNr="";
...
after success, navigates to orderlist page, so I have also OrderBean.
#ManagedBean(name = "OrderBean")
#SessionScoped
public class OrderBean {
List<Ordery> sdList;
public List<Order> getSdList() {
try {
String identityNr ="";
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
LoginBean lBean = (LoginBean) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "loginBean");
identityNr =lBean.getIdentityNr();
sdList = DatabaseUtil.getOrderByIdentityNr(identityNr);
...
}
I don't need the whole LoginBean, just ManagedProperty "loginBeanIdentityNr". But this code below doesn't work (of course);
identityNr = (String) FacesContext.getCurrentInstance()
.getApplication().getELResolver()
.getValue(elContext, null, "loginBeanIdentityNr");
this time it returns null to me.
I think if I need whole bean property, I can inject these beans, right? So, do you have any suggestions for this approach? can<f:attribute> be used?
The #ManagedProperty declares the location where JSF should set the property, not where JSF should "export" the property. You need to just inject the LoginBean as property of OrderBean.
public class OrderBean {
#ManagedProperty(value="#{loginBean}")
private LoginBean loginBean; // +setter
// ...
}
This way you can access it in the OrderBean by just
loginBean.getIdentityNr();
Alternatively, if you make your OrderBean request or view scoped, then you can also set only the identityNr property.
public class OrderBean {
#ManagedProperty(value="#{loginBean.identityNr}")
private String identityNr; // +setter
// ...
}
Unrelated to the concrete problem: initializing String properties with an empty string is a poor practice.
I want to instantiate a generic bean with a type parameter, and have the correct dependents wired based on this type parameter.
Suppose I have:
#Named
public Parent<T> {
#Inject
Parent(Child<T> c) {
...
}
}
public interface Child<T> {}
#Named
public class ChildString implements Child<String> {}
#Named
public class ChildInteger implements Child<Integer> {}
And then I want to use Parent like this:
#Named
public class UseParent {
#Inject
Parent<String> p;
}
Spring will complain with "expected single matching bean but found 2: childString, childInteger".
What is the best way to have wire my beans in this scenario?
I haven't found a satisfactory way of doing this. The solution I'm using for now is to create a subclass of Parent that specifies the generic type, eg:
#Named
public ParentString {
#Inject
ParentString(Child<String> c) {
super(c);
}
}
#Named
public class UseParent {
#Inject
ParentString p;
}
I've a simple #Stateless EJB that looks like this (stripped of all logging and error handling):
#Stateless
public class CurrentUserBean {
#PersistenceContext
private EntityManager em;
#Produces #Named #LoggedIn
#SessionScoped
public User produceCurrentUser() {
Principal principal = Faces.getExternalContext().getUserPrincipal();
String username = (principal == null ? null : principal.getName());
return em.createNamedQuery("findByLogin", User.class)
.setParameter("login", username)
.getSingleResult();
}
}
Works fine when the user logs in with JSF. But the same user can also authenticate via webservice, where I can (need to?) get the user principal from SecurityContext in a bean controlled by JAX-RS (resteasy in my case):
public User doAuth(#Context SecurityContext ctx) {
return em.createNamedQuery("findByLogin", User.class)
.setParameter("login", ctx.getUserPrincial().getName())
.getSingleResult();
}
How can I unify these approaches so that the production of the current user object is the responsibility of only one class?
CDI allows you to inject the Principal directly. Just do this:
#Inject Principal userPrincipal;
And that will have the user name.
I have a JSF2 application. I have a login bean which is session scoped and a logout bean which is view scoped. When I login I use redirect and it works fine. However the logout fails with redirect. If I logout without redirect it works.
#ManagedBean
#ViewScoped
public class MbLogout extends BaseJsf {
private static final long serialVersionUID = 2992671241358926373L;
public String logout() throws DfException {
getFacesContext().getExternalContext().invalidateSession();
//return "login?faces-redirect=true"; // fails with this
return "login";
}
}
The login page has bindings to the login bean so I suspect this may have something to do with it, although I don't see why it doesn't work. The error is:
java.lang.IllegalStateException: Cannot create a session after the response has been committed
My guess is it's trying to create a session on the login page since I access the session bean although I don't see anything wrong with this and it works without redirect.
I'm using MyFaces 2.1.
I would recommend using a Servlet rather than a bean for logout, a managed bean (especially view scoped) is not fitting for the purpose of logging out. For example:
#WebServlet(name = "LogoutServlet", urlPatterns = {"/logout"}) // Can be configured in web.xml aswell
public class LogoutServlet extends HttpServlet {
private static final String redirectURL = "http://www.somepage.com";
#Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Destroys the session for this user.
if (request.getSession(false) != null) {
request.getSession(false).invalidate();
}
response.sendRedirect(redirectURL );
}
}
It seems to be related to the bean being in the view scope which should by itself be serialized in the session. Make it request scoped instead. The view scope doesn't make much sense for logout anyway.
#ManagedBean
#RequestScoped
public class MbLogout extends BaseJsf {
// ...
}
<p:editor value="#{editorBean.value}" widgetVar="editor" width="686"
height="390" language="en" align="center">
</p:editor>
Following is my rich-text editor bean picked up from primefaces
#ManagedBean(name = "editorBean")
#SessionScoped
public class EditorBean {
private static final String MANAGED_BEAN_NAME = "editorBean";
private String value;
public static EditorBean getCurrentInstance() {
return (EditorBean) FacesContext.getCurrentInstance()
.getExternalContext().getRequestMap().get(MANAGED_BEAN_NAME);
}
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Apart from this I have another bean say A. I have a method inside A that populates a HTML table. What I want is when the user opens the editor, it should be pre-populated with that HTML table data and of course the changes should get reflected into (String: value). Therefore, you can say that I am trying to tie up both the values together. I think it needs to be done with DI but somehow its not working. If someone can guide or quote an example, it would be really helpful.
One way to do it is rewrite your getValue() method to pick up the value from bean A.
And yes, the reference to your A bean should come from DI:
//injecting a reference to A
#ManagedPropery(value="#{A}") //or whatever is the name of your bean
private A beanA;
public void setBeanA(A beanA) {
this.beanA = beanA;
}
Or, with CDI, just:
#Inject private A beanA
Finally, your getValue method
public String getValue() {
return beanA.getValue()
}