xhtml not showing session scoped values - java

I have a ManagedBean that is Session Scoped that injects another two Session Scoped Beans, they both have their proper getter and setters.
My class is as follows:
#ManagedBean(name="oneClass")
#SessionScoped
public class OneClassController implements Serializable {
#ManagedProperty(value="#{myOtherBean}")
public AnotherClass another;
#ManagedProperty(value="#{requestBean}")
public RequestClass request;
public String foo() {
another = getAnotherService(request);
return "page?faces-redirect=true";
}
//getters and setters for AnotherClass and RequestClass
}
Now, the request class holds all the values for a web service request. Those values are filled within a form in a xhtml page.
When the user finishes filling up the request and fires the action from a button, it enters the foo method. The debug shows the request with the correct data, and when I call it, another gets filled up correctly.
Now, page.xhtml looks like this:
<h:outputText value="#{requestBean.agentId}" />
<h:outputText value="#{myOtherBean.name}" />
<h:outputText value="#{myOtherBean.lastname}" />
When page is rendered, all the values from the requestBean are showed correctly, but all the anotherBean values show up empty. Even refreshing the page won't help.
If I trigger a button in page.xhtml to print out in the action method the values from anotherBean:
log.info("Another name: " + another.getName());
they print out fine.
I have in web.xml the saving method set for the server.
By the way, this is not the real naming convention I am using, but right now I'm in another computer without any IDEs nor JDK whatsoever, so I'm trying to replicate the code the best I can.
How can I show the correct values in page?

Try using,
<h:outputText value="#{oneClass.another.name}" />
<h:outputText value="#{oneClass.another.lastname}" />
To view all the variables in sessionScope you can do a:
<h:outputText value="#{sessionScope}" />
This will confirm if "myOtherBean" is in session scope or not.

Related

property not found for method in JSF [duplicate]

I am building a JSF application. I defined the GUI and did the select statements query the database using select.
Now I must do the insert statements, but I don't know how to read the value of a JSF input component like <h:inputText> and send it to my bean which performs the insert.
Should <h:inputText> value be mapped through faces-config.xml, so I can have it in my Java code?
You need to put all <h:inputXxx>/<h:selectXxx> components in a <h:form> and bind their value attribute to a bean property via an EL expression like #{bean.property}, backed by a getter/setter pair. When properly set, JSF will automatically set the values in the bean when the form is submitted via a <h:commandXxx> component in the very same form. You can specify a bean action method in action attribute of the <h:commandXxx> component via an EL expression like #{bean.action}, which points to the bare method action(). All submitted values are available right away there the usual Java way.
Given this JSF form example with one input field and one select field:
<h:form>
<h:inputText value="#{bean.text}" required="true" />
<h:selectOneMenu value="#{bean.choice}" required="true">
<f:selectItem itemValue="#{null}" />
<f:selectItem itemValue="One" />
<f:selectItem itemValue="Two" />
<f:selectItem itemValue="Three" />
</h:selectOneMenu>
<h:commandButton value="submit" action="#{bean.submit}" />
<h:messages />
<h:outputText value="#{bean.result}" />
</h:form>
The following bean prints the submitted values to the stdout, proving that JSF has already set the values long before the moment you access it in the action method.
package com.example;
import javax.inject.Named;
import javax.enterprice.context.RequestScoped;
#Named // Use #javax.faces.bean.ManagedBean on outdated environments.
#RequestScoped // Use #javax.faces.bean.RequestScoped on outdated environments.
public class Bean {
private String text;
private String choice;
private String result;
public void submit() {
result = "Submitted values: " + text + ", " + choice;
System.out.println(result);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getChoice() {
return choice;
}
public void setChoice(String choice) {
this.choice = choice;
}
public String getResult() {
return result;
}
}
That's all. Turning the regular form into an ajax form is a matter of nesting a <f:ajax> in the command component as below.
<h:commandButton value="submit" action="#{bean.submit}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
You can find another example and valuable links at bottom of our JSF wiki page.
Do note that whatever you intend to do with the submitted values is beyond the responsibility of JSF. For example, manipulating it, passing into another class, saving it in database, etc. None of this all is related to JSF. It has as being a HTML form based framework already done its job of providing you the submitted values in flavor of usable Java variables. The remainder is up to you.
To investigate the next step, you should at this point just be doing as if you've already a bunch of prepared / hardcoded variables instead of a whole JSF based user interface. For example, in order save to the values in a database, people usually use a business service layer framework like EJB which in turn uses a persistence layer framework like JPA. Some people even use "plain vanilla" JDBC for that. For more links to concrete examples, start here: JSF Controller, Service and DAO.

how can I send a value from my view to my bean using primefaces?

I am sending values to my view from my bean and from my view to my bean, everything is fine if I work with event such as "acitonListener" but now I want to send the user to other page (with a navigation rule, it works perfect) when I click on a button, but before of that I want to set in my bean one value, how can I do this?
I am doing something like this
<p:commandButton value="Send" id="sendButton" action="#{myBean.myMethod}"
update=":form:growTop" >
</p:commandButton>
Before of that there is only a table with <h:outputText/> with values from my bean, any way to do this?
Thanks
action="#{myBean.myMethod(myParameter)}
The above method expression will send myParameter to the myMethod function in your backing bean:
public void myMethod(String myParameter) {
// ...
}
You can also send the user to the next page by returning a valid navigation outcome from your action method:
public String myMethod(String myParameter) {
// ...
return "myPage?faces-redirect=true";
}
In your concrete case if there is a backing bean value which is printed out:
<h:outputText value=#{myBean.myParameter}/>
the following action
<p:commandButton value="Send" id="sendButton" action="#{myBean.myMethod(myParameter)}
update=":form:growTop" >
</p:commandButton>
will pass myParameter to your action method.
In order to get the expected behavior with primefaces datatable use at least #ViewScoped backing bean behind your table values.

How can I tell the Facelets page, what object it shall load, when the user returns the form?

I had a problem, which I solved, but I feel like my solution is a bad hack. Is there a better way?
I have a page, on which I placed the form, which shows properties of some object, as in example (obvious details omitted).
Ticket.java:
#Entity
public class Ticket {
#Id
private Long id;
private String title;
private byte priority;
// Getters, setters...
}
TicketController.java
#RequestScoped
public class TicketController {
private Ticket ticket = new Ticket();
// Getters, setters...
public String doUpdateTicket() {
Ticket t = ticketEJB.getTicketById(ticket.getId());
t.setTitle(ticket.getTitle());
t.setPriority(ticket.getPriority());
ticketEJB.updateTicket(t);
ticket = t;
return "view.faces";
}
}
edit.xhtml (just the form, everything else is boilerplate)
<h:form>
<h:inputHidden value="#{ticketController.ticket.id}" />
<h:panelGrid columns="2">
<h:outputLabel value="ID"/>
<h:outputLabel value="#{ticketController.ticket.id}"/>
<h:outputLabel value="Title: "/>
<h:inputText value="#{ticketController.ticket.title}"/>
<h:outputLabel value="Priority: "/>
<h:inputText value="#{ticketController.ticket.priority}" />
<h:commandButton value="Submit"
action="#{ticketController.doUpdateTicket}" />
</h:panelGrid>
</h:form>
Also there is TicketEJB, which is responsible for fetching those tickets, persisting, etc.
So I create a hidden input in the form, then (in managed bean) I find ticket, using provided id, then manually copy all the fields from ticket object of managed bean to the fetched ticket, then persist it... It involves the violation of DRY principle (I already stumbled on a bug when I added a field to Ticket, but forgot to copy it in the doUpdateTicket().
So, maybe there is a better way to do this?
Just get the original ticket from the EJB during preRenderView of a view scoped bean instead of creating a new one yourself. Assuming that the ticket ID is been passed as a request parameter with name id:
edit.xhtml
<f:metadata>
<f:viewParam name="id" value="#{ticketController.id}" />
<f:event type="preRenderView" listener="#{ticketController.preLoad}" />
</f:metadata>
...
TicketController
#ManagedBean
#ViewScoped
public class TicketController {
private Long id;
private Ticket ticket;
#EJB
private TicketEJB ticketEJB;
public void preLoad() {
ticket = ticketEJB.getTicketById(id);
}
public String doUpdateTicket() {
ticketEJB.updateTicket(ticket);
return "view.faces";
}
// ...
}
The only difference is that the input fields don't blank out. But isn't that just the whole idea behind an "edit" form? That issue is then also immediately fixed that way.
Oh and your
<h:outputLabel value="#{ticketController.ticket.id}"/>
really needs to be a
<h:outputText value="#{ticketController.ticket.id}"/>
You could add the Ticket as a ManagedBean in its own right but use #SessionScoped. This way the Ticket Domain Object keeps its id between requests and JSF can update it directly. Of course you lose the advantage of keeping data short lived with this approach, which you currently get via the Request scope. And you open a debate about binding to the Domain Object itself.
With JSF 2 you also have the View Scope where you can store attributes against the UIViewRoot, which may be highly desirable in your case to avoid using the hidden fields i.e. store the Ticket or Controller which HAS-A Ticket in viewScope - so while the user postbacks to the edit page the Ticket is kept in scope. Some folk may say you should be using a Transfer Object here to decouple the Service entities from the presentation tier - so update a TO, pass that to the EJB and let the EJB handle the update and persistence of the Entity.
Alternatively you could store just the Long id server side in #SessionScoped or #ViewScoped, as it may be insecure to store this as a hidden field as the client could change it to update another ticket. If you do use another instance of Ticket to capture UI Inputs then you could provide a Copy Constructor on the Ticket object, so the doUpdateTicket method itself does not include the tedious copy fields from one Ticket to another code.
To avoid repetition I would prefer binding directly to the JPA Entity AKA Domain Object. And I would use #ViewScoped.

JSF property transfer from backing bean A to backing bean B

I'm getting deeper into JSF 2.0 at the moment and lacking a bit of understanding about the "transport" of managed bean properties from one view to the other. I searched a bit but haven't found a really good example, so if anyone could point me to a tutorial or explain the things a little bit I'd really grateful.
So here is my scenario:
I'm developing a small playground calendar application. The first view select.xhtml contains the calendar selector, where the user can pick a specific date:
<html>
...
<h:form>
<!-- Calendar selector from primefaces -->
<p:calendar value="#{calendarSelect.date}" mode="inline" navigator="true" />
<p:commandButton value="Show entries for date" action="day" />
...
My corresponding backing bean looks like this:
#ManagedBean(name="calendarSelect")
#RequestScoped
public class CalendarSelectComponent {
private Date date = null;
... // Getters and setters
Now when I submit the form from select.xhtml I'm forwarded to day.xhtml
<html>
...
<h:form>
The current day ist:
<h:outputText value="#{calendarEdit.date}">
<f:convertDateTime pattern="dd.MM.yyyy" />
</h:outputText>
The backing bean now looks like this:
#ManagedBean(name="calendarEdit")
#ViewScoped
public class CalendarEditComponent implements Serializable {
private Date date = null;
private CalendarEntryBean currentEntry = null;
private List<CalendarEntryBean> allEntries = null;
....
I am now trying to solve the problem: How do I transfer the date parameter from the selector to the editor?
I've tried a number of options, one was this:
<p:commandButton value="Show entries for date" action="day" />
<f:setPropertyActionListener target="#{calendarEdit.date}" value="#{calendarSelect.date}" />
</p:commandButton>
A debugger shows, that indeed, the date property of the calendarEdit is populated with the value from calendarSelect, but since day.xhtml is a new view, a new CalendarEditComponent backing bean is being created and not the one I've populated with the date from the selector in the select view.
I've read that one solution would be to create a SessionScoped backing bean that does retain all it's values. But this is not the way I think it's supposed to work, because I don't really need the information in the session, I simply want it to "travel" from A to B. Another downside with the session based approach is that I can only use one selector and one editor per session - which I think isn't acceptible if you think of multi window browsing and so on.
I really don't think I'm the first one encountering such a scenario and I'm sure that JSF provides an elegant solution for this but I haven't been able to find that solution.
So once again, if anyone knows how to approach this - I'm listening! ;-)
The <f:setPropertyActionListener> is executed during invoke action phase of the form submit. So it expects that the value is still there at that point. But since your select bean is request scoped, it isn't there during form submit anymore. You want instead to pass a request parameter which get inlined in the output during render response. You can do this with <f:param>.
<p:commandButton value="Show entries for date" action="day" />
<f:param name="date" value="#{calendarSelect.dateAsString}" />
</p:commandButton>
It'll be available as request parameter (note that it only understands Strings, due to the nature of HTTP). You could let JSF set request parameters as managed properties, but since your edit bean is view scoped, this isn't possible with #ManagedProperty. You've got to gather it yourself by ExternalContext.
String dateAsString = externalContext.getRequestParameterMap().get("date");
True, that's clumsy. I would just have used the same bean and view for this and toggle visibility of select/edit forms by rendered attribute. The edit view is after all not directly openable/bookmarkable by a simple GET, isn't it? ;)

JSF2 DataBinding Problem

I have a little issue regarding submit of forms in jsf 2:
In my webapp I got a function that updates entities in my db. This function gets the relative data out of a managed bean.
So, my issue is that changes in my view are not passed to the managedBean. To make that clear for you, here an example:
public String updateProject() {
projectService.updateProject(projectData.getProjectDTO());
return ("overview.xhtml");
}
prjectData is my ManagedBean. This one doesn't work! No updates are been made.
public String deleteProject() {
projectData.getProjectDTO().setDeleted(true);
projectService.updateProject(projectData.getProjectDTO());
return ("overview.xhtml");
}
Here, when I change a value by code it works! So I guess my values out of the view are not passed to my managedBean.
Where could be a mistake? Is there maybe an action I have to invoke to make the data pass my view to the managedBean?
Answer to Gabor's comment:
My page looks like:
<h:form>
<h:commandLink action="#{controller.updateProject}" value="Edit" />
<h:outputLabel for="title" value="Titel" />
<h:inputText id="title" value="#{projectData.projectDTO.title}" />
</h:form>
If I change the title here and press update nothing happens ;-)
My Controller looks like:
#ManagedBean
#RequestScoped
public class Controller {
#ManagedProperty(value = "#{projectData}")
private ProjectData projectData;
...
For unknown reason my debug mode in eclipse doesn't work anymore it ignores my breakpoints all the time. I gonna fix that and then I'll check about the instances. Sry -.-
Either projectData or projectDTO is not the right instance as you expect it to be. It's a completely different instance. Aren't you eagerly recreating/overriding beans? Don't you have multiple beans in the scope? Shouldn't it for example be #{controller.projectData.projectDTO.title}? Shouldn't the projectData instance in the controller be a managed property?
Is your projectData bean also RequestScoped? Try to change to ViewScoped. RequestScoped beans are recreated for each request, also ajax request. And what is scope of projectService?

Categories

Resources