JSF #ManagedProperty doesn't work - jsf

On various places they said that you should use #ManagedProperty to get a request parameters. The problem is that I try to get the token from the request string but it somehow stays null all the time.
The link where the page is with called looks like this:
http://example.com/faces/Check.xhtml?token=EC-8AT450931P272300C&ID=VKEFF29XNGNJG
The bean:
#Named(value = "bean")
#RequestScoped
public class Bean implements Serializable {
#Inject
private AccountBean account;
#Inject
private Service web;
#ManagedProperty(value = "#{param.token}")
private String token;
#ManagedProperty(value = "#{param.ID}")
private String id;
#PostConstruct
public void init() {
System.out.println("token: " + token);
}
The page
<ui:define name="content">
<h:form>
<pou:commandButton action="#{bean.test()}" value="complete"/>
</h:form>
</ui:define>
And other things I tried:
Map<String, String> e = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
This doesn't contain the request parameters also. Same goes for all the facesContext things where you can get requests with.
Help will be appreciated.
P.S. I can't change anything behind the ? cause its called from a program not in my reach

Okay made it work.
#Inject to pass params to a CDI #Named bean via URL
This was the solution just needed to add a few more things to my site
<ui:define name="content">
<h:form>
<h:inputHidden value="#{bean.token}"/>
<h:inputHidden value="#{bean.id}"/>
<pou:commandButton action="#{bean.test()}" value="complete"/>
</h:form>
</ui:define>
And remove the #{param.xxx} part from the naming
#Inject #HttpParam
private String token;
#Inject #HttpParam(value = "ID")
private String id;

Related

After migration from JSF #ManagedBean to CDI #Named, constructor called multiple times and submitted input values always null

Edit: The comment section solved my problem! The problem was that I was using incorrect imports for the Scopes.
I have a simple JSF application (login, pull data from database, allow user to edit data). It works well, I want to update the code to use CDI (Weld), but I am having trouble.
I am following / looking at: http://docs.jboss.org/weld/reference/latest/en-US/html/example.html
Original stuff without Weld:
login.xhtml
<h:form id="inputForm">
<h:panelGrid columns="2" cellpadding="5" cellspacing="1">
<h:outputText id="nameDesc" value="Name"></h:outputText>
<h:inputText id="nameInput" value="#{login.loginName}" binding="#{name}"></h:inputText>
<h:outputText id="passwordDesc" value="Password"></h:outputText>
<h:inputSecret id="passwordInput" value="#{login.password}" binding="#{password}"></h:inputSecret>
</h:panelGrid>
<h:commandButton value="Login" action="#{login.login(name.value, password.value)}"/>
</h:form>
LoginBean.java:
#ManagedBean(name="login")
#SessionScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty(value="#{db}")
private DatabaseBean db;
private String password;
private String loginName;
// other stuff and functions
public String getLoginName () {
return loginName;
}
public void setLoginName (String name) {
this.loginName = name;
}
public String getPassword () {
return password;
}
public void setPassword (final String password) {
this.password = password;
}
public void setDb(DatabaseBean db) {
this.db = db;
}
DatabaseBean.java:
#ManagedBean(name="db", eager=true)
#ApplicationScoped
public class DatabaseBean implements Serializable {
#PostConstruct
public void init() {
//... connect to database etc
}
}
---------What I tried to get it running with Weld (only changes from above to make it a bit shorter): --------
LoginBean.java, changed to #Named from #ManagedBean, added #Inject for DatabaseBean
#Named("login")
#SessionScoped
public class LoginBean implements Serializable {
// stuff
private #Inject DatabaseBean db;
}
DatabaseBean.java, changed to #Named from #ManagedBean:
#Named("db")
#ApplicationScoped
public class DatabaseBean implements Serializable {
}
LoginBean has a function:
public String login(String name, String password) {
System.out.println("login called"+name);
// other stuff
}
With my second implementation (the one where I try to use Weld), the print is called once: "login called", and the username is empty (I checked this with name.IsEmpty()).
I have also tried injecting it by constructor:
loginBean.java
#Inject
public LoginBean(DatabaseBean db) {
System.out.println("constructor");
this.db = db;
}
When I do this the I get lots of "constructor" prints, so it is called several times, but I don't see why - I guess this is the problem though, only one instance of LoginBean gets the input (username and password) and then lots of new ones are created for some reason. Why is that?
I use Eclipse and Tomcat8 to run it.
Thank you for reading!
managed bean constructor called multiple times
CDI may call constructor more often than expected while generating/creating enhanced subclasses/proxies. See also Field.get(obj) returns all nulls on injected CDI managed beans, while manually invoking getters return correct values. Just do not log constructor invocation, it would only confuse yourself. #PostConstruct is the only interesting method to hook on.
the print is called once: "login called", and the username is empty (I checked this with name.IsEmpty()).
As to the concrete problem of form input values being null when the action method is invoked, and thus the #SessionScoped CDI managed bean seemingly being recreated on every access, this matches the behavior of a #Dependent scoped bean. This is the default scope when no valid CDI managed bean scope can be found. See also What is the default Managed Bean Scope in a JSF 2 application?
This in turn suggests you imported #SessionScoped from the wrong package. Make sure it's from the javax.enterprise.context package and not from e.g. javax.faces.bean. JSF managed bean scopes are not recognizable as valid CDI managed bean scopes.
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
#Named("login")
#SessionScoped
public class LoginBean implements Serializable {
// ...
}

javax.el.PropertyNotFoundException: Target Unreachable, 'BracketSuffix' returned null

I am trying to insert multiple IPs in a List<String> using a simple example. But I am getting following error.
javax.el.PropertyNotFoundException: Target Unreachable, 'BracketSuffix' returned null
Here is my JSF 2.2 page:
<h:form id="form">
<ui:repeat value="#{exampleBean.ipAddresses}" var="s"
varStatus="status">
<h:inputText value="#{exampleBean.ipAddresses[status.index]}" />
</ui:repeat>
<h:inputText value="#{exampleBean.newIp}" />
<h:commandButton value="Add" action="#{exampleBean.add}" />
<h:commandButton value="Save" action="#{exampleBean.save}" />
</h:form>
And here is my backing bean:
#ManagedBean
#ViewScoped
public class ExampleBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> ipAddresses;
private String newIp;
#PostConstruct
public void init() {
ipAddresses= new ArrayList<String>();
}
public String save() {
System.out.println(ipAddresses.toString());
return null;
}
public void add() {
ipAddresses.add(newIp);
newIp = null;
}
public List<String> getIpAddresses() {
return ipAddresses;
}
public String getNewIp() {
return newIp;
}
public void setNewIp(String newIp) {
this.newIp = newIp;
}
}
How is this caused and how can I solve it?
javax.el.PropertyNotFoundException: Target Unreachable, 'BracketSuffix' returned null
The exception message is wrong. This is a bug in the EL implementation being used by the server. What it really meant here in your specific case is:
javax.el.PropertyNotFoundException: Target Unreachable, 'ipAddresses[status.index]' returned null
In other words, there's no such item in the array list. This suggests that the bean got recreated on form submit and therefore reinitializes everything to default. It thus behaves like a #RequestScoped one. Most likely you imported the wrong #ViewScoped annotation. For a #ManagedBean, you need to make sure that the #ViewScoped is imported from the very same javax.faces.bean package, and not thus the JSF 2.2-introduced javax.faces.view one which is specifically for CDI #Named beans.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
See also:
Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable
#ViewScoped bean recreated on every postback request when using JSF 2.2
Update: as per the comments, you're using WebSphere 8.5 which usually ships with an ancient MyFaces 2.0.x version. I reproduced your problem with MyFaces 2.0.5. Its <ui:repeat> failed to remember its view state for iteration status, that's why your construct still fails even though you're properly using a #ViewScoped bean. I could work around it by using <c:forEach> instead.
<c:forEach items="#{exampleBean.ipAddresses}" var="s" varStatus="status">
...
</c:forEach>
The alternate solution (apart from upgrading MyFaces to a more recent/decent version, obviously) would be to wrap the immutable String in a mutable javabean such as
public class IpAddress implements Serializable {
private String value;
// ...
}
so that you can use List<IpAddress> instead of List<String> and thus you don't need the varStatus anymore which triggered the MyFaces bug.
private List<IpAddress> ipAddresses;
private IpAddress newIp;
#PostConstruct
public void init() {
ipAddresses= new ArrayList<IpAddress>();
newIp = new IpAddress();
}
<ui:repeat value="#{exampleBean.ipAddresses}" var="ipAddress">
<h:inputText value="#{ipAddress.value}" />
</ui:repeat>
<h:inputText value="#{exampleBean.newIp.value}" />

Session Bean Data is lost after page reload or page change

I'm working on a JSF Project using a Wildfly 8 Server and jsf 2.2.
I've a web part with xhtml and beans + ejb part with models etc and a mysql database.
Part of Model (EJB part): Foo.java
String name = "";
Object Foo2 = new Foo2();
Part of Model (EJB part): Foo2.java
private static final long serialVersionUID = 1L;
String name = "";
Now I've input like this: input.xhtml
<f:metadata>
<f:event listener="#{ InputBean.init() }" type="preRenderView" />
</f:metadata>
<h:inputText
value="#{ InputBean.actualFoo.name }">
</h:inputText>
<h:selectOneMenu
value="#{InputBean.currentSelectedFoo2_ID}">
<f:selectItems value="#{InputBean.lhm_AllFoo2}" />
</h:selectOneMenu>
and a bean: InputBean.java
#SessionScoped
#ManagedBean(name = "InputBean")
public class InputBean implements Serializable
private static final long serialVersionUID = 1L;
private Long currentSelectedFoo2_ID;
private LinkedHashMap<String, Object> lhm_AllFoo2;
private Foo actualFoo;
public InputBean() {
lhm_AllPermissions = new LinkedHashMap<String, Object>();
actualFoo = new Foo();
}
public void init()
// Method of interface in EJB part which gives me all Foo2 to a list
List<Foo2> list_AllFoo2 = foo2Interface.getAllFoo2;
if ((list_AllFoo2 != null) && (list_AllFoo2.size() > 0)) {
for (Foo2 foo2 : list_AllBFoo2) {
lhm_AllFoo2.put(foo2.getName(), foo2.getId());
}
}
When I input data in the inputField and select data the selectonemenu and then reload the page (f5) or change to another page (of the same project) and go back the data in the input field is still avaiable but the selectonemenu is reseted to the default value.
I tried to debug the problem, but the data is already lost when the init is accessed, no setter of the bean is called before. The constructer isn't called too, so everything seems to be correct. The bean data which isn't linked to an input isn't lost too.
Is this a normal JSF problem and is there a way to solve that?

Named Bean not injected into another named bean

I am trying to inject a named bean in another one.
When I try to access properties of the injected bean , it returns null which means that the injection fails.
Here is the first Bean:
#Named
#SessionScoped
public class FirstMBean {
String caracter;
..........
public String goToNext(){
String caracter=FacesContext.getCurrentInstance().getExternalContext().
getRequestParame‌​terMap().get("caracter"); this.caracter=caracter;
System.out.println("the selected caracteris"+ caracter);
return "/pages/next?faces-redirect=true"; }
}
The second named bean:
#Named
#SessionScoped
public class SecondMBean {
#Inject
FirstMBean firstMBean ;
String injectedCaracter ;
#PostConstruct
public void init() {
this.injectedCaracter = this.firstMBean.getCaracter();
System.out.println("injectedCaracter ----" + this.injectedCaracter);
}
In my .xhtml page :
<p:commandButton value="see caracter" action="#{firstMBean.goToNext}">
<f:param name="caracter" value="#{caracter}" />
</p:commandButton>
Please note that I am using tomcat server to which I added WELD to support CDI AND when I put the scope to ApplicationScoped, everything works fine.

How to share data between two #ViewScoped beans?

I am trying to pass id (long) from one.xhtml to another .xhtml.
Both the backing beans are #ViewScoped and I am trying to share long id between them.
I am getting error with <f:viewParam/>
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to create
managed bean saleOrder. The following problems were found:
- The scope of the object referenced by expression #{param.foo}, request, is shorter than the referring managed beans (saleOrder) scope of view.
I am have following code.
#ManagedBean
public class InvoiceView{
private long number;
// setter getter.
}
#ManagedBean
#ViewScoped
public SearchInvoice{
private List<InvoiceView> views;
private InvoiceView selectedView; // this is coming from <p:dataTable>
}
#ManagedBean
#ViewScoped
public class SaleOrder {
#ManagedProperty("#{param.foo}")
private String number;
#PostConstruct
public void init(){
//sysout number;
}
}
I have following code in searchInvoice.xhtml file.
<!-- I have not desclared <f:metadata/> -->
<h:commandButton value="Place Sale Order"
action="#{searchInvoice.forwardToSaleOrder}" <!-- this return saleOrder.xhtml string -->
rendered="#{not empty searchInvoice.views}">
<f:viewParam name="foo" value="#{searchInvoice.selectedView.number}" />
</h:commandButton>
You can use <f:viewParam> (JSF 2) in saleOrder.xhtml, which works with view scoped beans.
Check out this article.

Resources