How to populate injected bean in jsf - jsf

I have a simple form :
<h:form>
<h:inputText value="#{storyController.story.author}"/>
<h:commandButton action="#{storyController.save}" value="save"/>
</h:form>
and a bean like this :
#Model
public class Story {
private String author;
//getter and setter...
}
and a controller :
#Model
public class StoryController {
private StoryService storyService;
private Story story;
#Inject
public StoryController(StoryService storyService, Story story) {
this.storyService = storyService;
this.story = story;
}
public String save() {
System.out.println(story.getAuthor());
return "index.xhtml";
}
public Story getStory() {
return story;
}
public void setStory(Story story) {
this.story = story;
}
}
Now when I fill the author field and click on save button, the bean is not populated (the bean is injected correctly, it's not null).
If instead I do story = new Story() in constructor, then the bean is correctly populated. I want to avoid doing, this, I think that injecte bean is a better practice right?
I tried to set input value like : #{story.author} but still not populated.
What am I doing wrong?

Related

For exact same JSF EL expression, getter is being called for ouputText but not for inputText. Why?

This is my JSF pages
<h:form>
First Name: <h:inputText value="#{userBean.first}" valueChangeListener="#{userBean.updateLastName}" onblur="submit()"/><br/>
Last Name: <h:inputText value="#{userBean.last}"/><br/>
Last Name: <h:outputText value="#{userBean.last}"/><br/> </h:form>
Following is the managed bean code.
#Named
#RequestScoped
public class UserBean {
private Map<String, String> names;
private String first, last;
public UserBean() {
names = new HashMap<>();
names.put("first1", "last1");
names.put("first2", "last2");
}
public String getFirst() {return first;}
public void setFirst(String first) {this.first = first;}
public String getLast() {return last;}
public void setLast(String last) {this.last = last;}
public void updateLastName(ValueChangeEvent e){
last = names.get(e.getNewValue().toString());
FacesContext.getCurrentInstance().renderResponse();
}
}
Now, when I type "first1" on the FirstName field and tab out, I see "last1" on the outputText field but inputText field remains empty.
I did the debugging and found getter is being called only once, so I wonder why getter is not being called for the inputText? Considering EL Expression is exactly same and based on my knowledge getter should be called during Render Response phase???

Show how many Users logged in with JSF

i trie to run this code
#ManagedBean
#ApplicationScoped
public class Controller implements Serializable {
private static final long serialVersionUID = 1L;
private Benutzer benutzer;
private List<Erfasst> bisherErfasst = new ArrayList<Erfasst>();
private EntityManagerFactory emf = Persistence
.createEntityManagerFactory("CP Kontrolle");
private static Controller instance = new Controller();
public Benutzer getBenutzer() {
return benutzer;
}
public boolean anmelden(String email, int kdnr) {
EntityManager em = emf.createEntityManager();
Query query = em
.createQuery("SELECT b FROM Benutzer b WHERE b.email = :email AND b.kdnr = :kdnr");
query.setParameter("email", email);
query.setParameter("kdnr", kdnr);
List<Benutzer> liste = query.getResultList();
em.close();
if (liste.size() == 1) {
benutzer = liste.get(0);
AngemeldeteBenutzer.getAb().hinzufuegen(benutzer);
return true;
} else {
return false;
}
}
public static Controller getInstance() {
return instance;
}
[....]
}
}
The above code is my ControllerBean. From the Login-Form, user data will be checked in the "anmelden" Class and return true or false if it was successfully.If successfully, the user will be store into a list, as you can see.
#ManagedBean
#ApplicationScoped
public class AngemeldeteBenutzer implements Serializable {
private static final long serialVersionUID = 1L;
private List<Benutzer> online = new LinkedList<Benutzer>();
private static AngemeldeteBenutzer ab = new AngemeldeteBenutzer();
public static AngemeldeteBenutzer getAb() {
return ab;
}
public List<Benutzer> getOnline() {
return online;
}
public void hinzufuegen(Benutzer benutzer) {
online.add(benutzer);
}
}
This is my other Bean, which store the successfully logged user into a list.
Now i want to list all user into my table, but my table is still empty. No errors!
<h:panelGrid columns="2" id="onlinePanel" >
<h:dataTable value="#{angemeldeteBenutzer.online}" var="on">
<h:column>
<f:facet name="header">Email</f:facet>
<h:outputText value="#{on.email}"></h:outputText>
</h:column>
</h:dataTable>
</h:panelGrid>
The mistake is here:
private static Controller instance = new Controller();
public static Controller getInstance() {
return instance;
}
private static AngemeldeteBenutzer ab = new AngemeldeteBenutzer();
public static AngemeldeteBenutzer getAb() {
return ab;
}
You seem to have missed the point of a bean management framework with dependency injection support. You seem to be expecting that #{angemeldeteBenutzer} in the JSF page is referring exactly the same instance as you manually created there with new operator and are filling with users.
This is Wrong! You have there two instances of the class, one automatically created by JSF and available via #{angemeldeteBenutzer} and another one manually created by yourself and available via that getAb() method only.
Get rid of all those static fields and methods. They don't belong there. Instead, use #ManagedProperty to let JSF inject managed beans in each other. Add this code to the Controller class.
#ManagedProperty("#{angemeldeteBenutzer}")
private AngemeldeteBenutzer ab;
public AngemeldeteBenutzer getAb() {
return ab;
}
public void setAb(AngemeldeteBenutzer ab) {
this.ab = ab;
}
And replace in the same Controller class this line
AngemeldeteBenutzer.getAb().hinzufuegen(benutzer);
by
ab.hinzufuegen(benutzer);
Note: if you're already on Java EE 7, consider using CDI #Named instead of JSF #ManagedBean. When injecting via #Inject instead of #ManagedProperty, you don't need those ugly getter/setter anymore.
#Named
#ApplicationScoped
public class AngemeldeteBenutzer {
}
#Named
#ApplicationScoped
public class Controller {
#Inject
private AngemeldeteBenutzer ab;
}
Unrelated to the concrete problem, the Controller doesn't seem to be a legit application scoped bean. It looks too much like a view scoped bean due that view-specific variables and business logic. Make sure you understand the scopes: How to choose the right bean scope?

Search function not doing anything

sorry if this is a poor question but this one feature have been driving me mad for days so i thought id post it here to see if you guys can help me
basically all i want to do from a jsf page have the user search a user and for me to return all the details
<h:form id="searchForm">
<h:outputLabel value="Search: " style="font-weight:bold" />
<h:inputText id="search" value="#{userdetailsController.search}" />
<h:commandButton value="Search" action="index"/>
</h:form>
that is the jsf page, working fine
it calls my userdetailsController class
#Named("userdetailsController")
#SessionScoped
public class UserdetailsController implements Serializable {
private Userdetails current;
private DataModel items = null;
#EJB
private Richard.beans.UserdetailsFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
private String search;
public String getSearch() {
System.out.println("inGetSearch");
return search;
}
public void setSearch(String search) {
this.search = search;
}
......
a contactsService class
#Stateless
public class ContactsService {
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
#EJB
private UserdetailsFacade cf;
public List<Userdetails> searchByString(String string) {
return cf.searchByString(string);
}
public List<Userdetails> getAllPersons() {
return cf.findAll();
}
}
an AbstractFacade class
/* trying out a search function */
public List<T> searchByString(String string) {
System.out.println("in SearchByString");
return getEntityManager().createNamedQuery("Userdetails.findByUsername").setParameter("string", "%" + string + "%").getResultList();
}
and the Userdetails class with the query i am trying to search
#NamedQuery(name = "Userdetails.findByUsername", query = "SELECT u FROM Userdetails u WHERE u.username = :username")})
currently only the getters and settings are working in Getsearch
how can i make this work as i have spent days on this feature and are still no closer, sorry this is my first time at this
thanks guys
EDIT
would adding
public List<Userdetails> getAllPersons() {
if (search == null) {
return cs.getAllPersons();
}
return cs.searchByString(search);
}
in the UserdetailsController be enough ?
You're not invoking any action here:
<h:commandButton value="Search" action="index"/>
So it's indeed logical that it isn't "doing anything".
You need to invoke a managed bean action which in turn executes the desired code to obtain the desired data from the DB and assign to a property:
<h:commandButton value="Search" action="#{userdetailsController.submit}" />
with inside UserdetailsController:
private String search;
private List<UserDetail> items; // No need for DataModel here.
#EJB
private UserdetailsFacade ejbFacade;
public String submit() {
items = ejbFacade.searchByString(search);
return "index";
}
Your whole ContactsService seems useless by the way.
As per your attempt in the getter method in the update of your question, please don't do that. You should never call the DB in a getter method for the reasons mentioned in Why JSF calls getters multiple times

Using a Enum with a ActionParam

I am using the following piece of code in my JSF 2.0 with RichFaces 4.0. I have a managed bean that has an enum. Now i want to assign the value of the enum via an ActionParam. How can I do this? Here is the code:
<a4j:commandLink id="pendingTransactions"
action="#{tellerBean.getPendingTransactions}" value="Show Pending"
styleClass="button category-btn">
<a4j:actionparam name="first" value=""
assignTo="" />
</a4j:commandLink>
and my managed bean:
#ManagedBean
#SessionScoped
public class TellerBean implements Serializable{
public enum TransactionType {
PENDING,PROCESSED,ALL
}
private static final long serialVersionUID = -321111;
private String recipientID;
private String recipientName;
private String transactionAmount;
private TransactionType transactionType;
public String getRecipientID() {
return recipientID;
}
public void setRecipientID(String recipientID) {
this.recipientID = recipientID;
}
public String getRecipientName() {
return recipientName;
}
public void setRecipientName(String recipientName) {
this.recipientName = recipientName;
}
public String getTransactionAmount() {
return transactionAmount;
}
public void setTransactionAmount(String transactionAmount) {
this.transactionAmount = transactionAmount;
}
public void searchTransactions() {}
public TransactionType getTransactionType() {
return transactionType;
}
public void setTransactionType(TransactionType transactionType) {
this.transactionType = transactionType;
}
public void getTransactions() {}
}
Now I want to assign the value of the transactionType variable to an Enum value. How can I do this?
I don't know what you want to do with the variable or how you want to display it, so here's a generic example.
First of all, the JSF page must be able to 'iterate' over the enum to discover the possible values. I'm using h:selectOneMenu as an example which is filled using f:selectItems. f:selectItems expects a List<> as input so we need to create a method in the TellerBean:
public List<TransactionType> getTransactionTypes()
{
List<TransactionTypes> tt = new ArrayList<TransactionType>();
for (TransactionType t : TransactionType.values())
{
tt.add(new TransactionType(t, t.toString()))
}
return tt;
}
Then for an example JSF page:
<h:form>
<h:selectOneMenu value="#{tellerBean.transactionType}">
<f:selectItems value="#{tellerBean.transactionTypes}"/>
</h:selectOneMenu>
<h:commandButton value="Submit" action="#{tellerBean.someMethod}"/>
</h:form>
The JSF page should display a drop-down list with the values of the enum. When clicking the button labeled "Submit" it executes someMethod() in TellerBean. Of course this doesn't work because the method doesn't exist, but it's just an example. ;-)

#ManagedProperty - Inject one request scoped bean into another request scoped bean

I have this SearchBean:
#ManagedBean(name = "searchBean")
#RequestScoped
public class SearchBean implements Serializable
{
private String input = null;
// getter methods
public String getInput() {
return input;
}
// setter method
public void setInput(String input) {
this.input = input;
}
public String Submit() {
return null;
}
}
Can I inject it into another bean using #ManagedProperty. For example:
#ManagedBean(name = "bookBean")
#RequestScoped
public class BookBean implements Serializable
{
#ManagedProperty(value = "#{searchBean}")
private SearchBean searchBean;
#PostConstruct
public void init()
{
System.out.println("Value: " + searchBean.getInput());
}
public SearchBean getSearchBean() {
return searchBean;
}
public void setSearchBean(SearchBean searchBean) {
this.searchBean = searchBean;
}
}
And the Facelet (search.xhtml):
<h:form id="formSearch">
<h:commandButton value="Search" action="#{searchBean.Submit}" />
</h:form>
UPDATE: I have search.xhtml inserted into book.xhtml via a ui:insert component as follow:
<h:form id="formBooks">
<ui:insert name="search">
<ui:include src="/templates/common/search.xhtml"/>
</ui:insert>
</h:form>
The searchBean.getInput() method above should return a value as a result of a form's submission. Is the above method of injection possible?
I assume that SearchBean.input will be bound to an input field:
public class SearchBean implements Serializable {
private String input = null;
Something like this:
<h:inputText value="#{searchBean.input}" />
If so, then this will be null:
#PostConstruct
public void init()
{
System.out.println("Value: " + searchBean.getInput());
}
But, assuming a value has been set, it will not be null when this method is invoked:
public String Submit() {
return null;
}
Image from Richard Hightower's JSF for nonbelievers: The JSF application lifecycle.
The reason is due to how the JSF lifecycle works:
When #{searchBean...} is first resolved and found not to exist:
The bean is instantiated
Any dependency injections are performed (there aren't any in this case)
#PostConstruct method is invoked
The bean is placed into scope
Assuming the Apply Request Values and Validations phases succeed, SearchBean.setInput(String) is invoked in the Update Model Values phase
SearchBean.Submit() is invoked in the Invoke Application phase
This process is defined in the JSF specification.
Now, if SearchBean.input were injected directly from the parameter map, it would not be null during #PostConstruct:
#ManagedProperty(value = "#{param.someParamName}")
private String input;
However, there aren't any real advantages to this - you're skipping any input validation and you can't use SearchBean.input as a field binding because it will be overwritten in the Update Model Values phase.
The SearchBean.Submit() method is where your application logic for performing the search should go.

Resources