When I run this the code below, Apache Tomcat Log says:
Property 'recuClientes' not found in type com.swc.rc.recu.UtilsRecu
The webPage returns No records found.
any suggestion?
This is the call
<p:outputPanel>
<h:form>
<p:dataTable var="rec" value="#{rc.recu}">
<p:column headerText="recu">
<h:outputText value="#{rec.deudor}" />
</p:column>
</p:dataTable>
</h:form>
</p:outputPanel>
This is the source,
i can use it, isnĀ“t it?
#XmlTransient
public Collection<Procs> getProcsCollection() {
return procsCollection;
}
public void setProcsCollection(Collection<Procs> procsCollection) {
this.procsCollection = procsCollection;
}
And this is the managedBean..
#ManagedBean(name = "rc")
#SessionScoped
public class UtilsRecu {
private Clientes cliente=new Clientes();
private List <Procs> recu=new LinkedList<Procs>();
public void recuClientes(){
recu=(List<Procs>) cliente.getProcsCollection();
}
public void setRecu(List<Procs> recu) {
this.recu= recu;
}
public List<Procs> getRecu() {
recuClientes();
return recu;
}
}
Thank you..
The exception which you're facing is not caused by the Facelets code shown so far. It's caused by incorrect usage of #{rc.recuClientes} somewhere else in the same page. Perhaps you have placed it plain vanilla in template text like so
#{rc.recuClientes}
and hoping that it would execute the method on load. But it doesn't work that way. It would be interpreted as a value expression and it would thus be looking for a getter method getRecuClientes() which returns something which can then be printed to the output. But as such a getter method does not exist, exactly the "property not found" exception would be thrown which you're facing.
Given the fact that this method performs some business logic (filling the list), it should be invoked by some action component such as <h:commandButton>.
<h:form>
<h:commandButton value="Submit" action="#{rc.recuClientes}" />
</h:form>
Or, if you intend to invoke it during the initial GET request already, then just annotate it with #PostConstruct without the need to reference it anywhere in the view.
#PostConstruct
public void recuClientes() {
recu = (List<Procs>) cliente.getProcsCollection();
}
This way it will be invoked directly after bean's construction.
By the way, that cast is a code smell. In well designed code, you shouldn't have the need for that cast in this particular construct.
Related
I am using a Button in JSF with Primefaces. I made a bean (SearchActions) that have two methods. Both of them have a parameter with an interface-type (IOrder).
The class Order (which is delivered through the methods) implemets the IOrder-interface.
This is the error I get at viewing the page:
java.lang.NoSuchMethodException:
....SearchActions.hasOrderStatus(....jpa.model.Order,
java.lang.String)
This is my button (the method in the "actionListener" works fine, but the method in the "disabled" does not)
<p:commandButton value="Reopen" actionListener="#{searchActions.setOrderStatus(order, 'open')}" disabled="#{!searchActions.hasOrderStatus(order, 'open')}" ajax="false" />
These are the two classes that I use:
public class Order implements IOrder
{
...
}
public class SearchActions
{
public void setOrderStatus( IOrder order, String statusString ) throws IOException
{
...
}
public boolean hasOrderStatus( IOrder order, String statusString ) throws IOException
{
...
}
}
So.. Why does it work with the first method (setOrderStatus) but not with the second method (hasOrderStatus)?
I hope, someone can help me.
Thanks!
java.lang.NoSuchMethodException: ....SearchActions.hasOrderStatus(....jpa.model.Order, java.lang.String)
means that
order is not from type jpa.model.Order
maybe wrong imports in your bean?
Looking directly at the tag will be easier to understand my problem, the question goes inside the styleClass attribute:
<h:outputText value="#{prod.actualStock}"
styleClass="
#{productBean.getSeverity(prod.actualStock, prod.replacementAlertLevel).equals('INFO') ?
'severity-info' : productBean.getSeverity(prod.actualStock, prod.replacementAlertLevel).equals('WARN') ?
'severity-warn' : 'severity-danger'}" />
Now, note that I'm calling two times the 'getSeverity()' function, each of the three returns gives a different style class for the outputText. Is there a way to call the function only once keeping the same logic?
The '' tag goes inside a table.
You can add another attribute in your ProductBean class that holds the result of ProductBean#getSeverity and you set it in your managed bean before using it in the <h:dataTable>
#ViewScoped
#ManagedBean
public class Bean {
private List<ProductBean> productBean;
//getters and setters...
//I'm assuming you fill the list here
#PostConstruct
public void init() {
productBean = ...
for(ProductBean pb : productBean) {
pb.setSeverityValue(pb.getSeverity(<parameters>));
}
}
}
In your JSF code, you just call the property
<h:outputText value="#{prod.actualStock}"
styleClass="#{productBean.severityValue.equals('INFO') ? 'severity-info' : productBean.severityValue.equals('WARN') ? 'severity-warn' : 'severity-danger'}" />
Why not just have the getSeverity method return the class name as a string?
I have this f:viewParam that I try to bind validate and convert a userId into Player, and I got an unexpected results.
<f:metadata>
<f:viewParam name="userId" value="#{myBean.selectedPlayer}" converter="pConverter"
converterMessage="Bad Request. Unknown User" required="true"
requiredMessage="Bad Request. Please use a link from within the system" />
</f:metadata>
<h:body>
<p:messages id="msgs"/>
<h:form>
<ul>
<li>Harry</li>
<li>Tom</li>
<li>Peter</li>
</ul>
</h:form>
<h:form>
<h:panelGrid columns="2" rendered="#{not empty myBean.selectedPlayer}">
<h:outputText value="Id: #{myBean.selectedPlayer.id}"/>
<h:outputText value="Name: #{myBean.selectedPlayer.name}"/>
</h:panelGrid>
</h:form>
<h:form id="testForm">
<h:inputText value="#{myBean.text}"/>
<p:commandButton value="Switch" update=":msgs testForm"/>
<h:outputText value="#{myBean.text}" rendered="#{not empty myBean.text}"/>
</h:form>
</h:body>
My Converter look like this
#FacesConverter(value="pConverter")
public class PConverter implements Converter {
private static final List<Player> playerList;
static{
playerList = new ArrayList<Player>();
playerList.add(new Player(1, "Harry"));
playerList.add(new Player(2, "Tom"));
playerList.add(new Player(3, "Peter"));
}
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value == null || !value.matches("\\d+")){
return null;
}
long id = Long.parseLong(value);
for(Player p : playerList){
if(p.getId() == id){
return p;
}
}
throw new ConverterException(new FacesMessage("Unknown userId: " + value));
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object value) {
if(!(value instanceof Player) || value == null){
return null;
}
return String.valueOf(((Player)value).getId());
}
}
As I click the three link (Harry, Tom, Peter), the converter work great. It converter the id and bind the player back to my managed bean. I then type something in the text box, then click Switch, the first time it work fine, what I typed appear next to the button, but then I change what I type, and click Switch again, then error message appear Bad Request. Please use a link from within the system, which is the error message for required for f:viewParam. If I took the f:viewParam out then everything work fine. Surprisingly, if I switch from f:viewParam to o:viewParam (OmniFaces), then it work great.
That's because the <f:viewParam> runs on every single HTTP request, also on postbacks. It works in your case fine for plain GET links, because you're passing exactly that parameter in the links. It fails in your case for POST forms, because you aren't passing that parameter in the button. So it becomes null in the request parameter map and the required validator kicks in and hence this validation error.
To keep the <f:viewParam required="true"> happy on POST forms as well, you basically need to retain the initial request parameter by <f:param> in the command buttons/links.
<p:commandButton value="Switch" update=":msgs testForm">
<f:param name="userId" value="#{param.userId}" />
</p:commandButton>
The OmniFaces <o:viewParam>, which is designed to be used in combination with view scoped beans, has an additional check in the isRequired() getter (source code here):
#Override
public boolean isRequired() {
// The request parameter get lost on postbacks, however it's already present in the view scoped bean.
// So we can safely skip the required validation on postbacks.
return !FacesContext.getCurrentInstance().isPostback() && super.isRequired();
}
So, this skips the required validator on every postback (and additionally, it also skips setting the model value on every postback due to its stateless nature). That's why you don't see the validation error and you still have the proper model value (which isn't reset on every postback).
I have a weird problem with a custom #FacesConverter with JBoss-7.1.0.CR1b during an AJAX call in p:selectOneMenu (Primefaces 3.0).
The simplified Converter looks like this, there are no NPE or other exceptions in this class
#FacesConverter("MyConverter")
public class MyConverter implements Converter
{
public Object getAsObject(FacesContext fc, UIComponent uic, String value)
{
logger.debug("getAsObject value: "+value);
if (submittedValue.trim().equals("")) {return null;}
else
{
MyEjb ejb = new MyEjb();
ejb.setId(Long.parseLong(value()));
return ejb; //**** alternative with return null; ****
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object value)
{
if (value == null || value.equals("")) {return "";}
else
{
MyEjb ejb = (MyEjb)value;
return ""+ejb.getId();
}
}
}
The converter is used in a p:selectOneMenu:
<h:form>
<p:selectOneMenu value="#{clientBean.selected}" converter="MyConverter">
<f:selectItems value="#{clientBean.all}" var="my"
itemLabel="#{my.name}" itemValue="#{my}"/>
<p:ajax listener="#{clientBean.changed}" />
</p:selectOneMenu>
</h:form>
That's not rocket engineering, the changed method simply makes a debug:
public void changed()
{
logger.info("changed() "+selected);
}
But now the annoying part: The changed() is never called with the code like above, but I get the converter invoked three times:
12:37:51,500 DEBUG getAsObject value: 35
12:37:51,502 DEBUG getAsObject value:
12:37:51,503 DEBUG getAsObject value:
If I change the p:selectOneMenu value="#{clientBean.selectedId}" to a long selectedId and don't use the Converter the method is called once. Even if I return null in getAsObject()the changed() is called (once). I don't assume it's Primefaces related, because I have the same behavior if I use h:selectOneMenu and f:ajax.
You should have a <p:messages />, <p:growl /> or <h:messages /> which is been ajax-updated in your view. You should also pay attention to warnings in server logs about possible missing faces messages. The chance is big that you're seeing the infamous Validation error: Value not valid validation error.
After conversion, JSF will validate if the submitted object is one of the available items as part of safeguard against tampered/hacked requests. JSF will do that by submittedObject.equals(oneOfAvailableObjects) for each of the available objects as you have there in <f:selectItems>. If nothing matches, then JSF will display this validation error.
In your particular case, the MyEjb class has apparently no equals() method or its implementation is broken. See also Right way to implement equals contract.
I've searched and tried various things from around here and the web; prependId, using full id paths (:form:panelid:componentid kinda thing), and others.
I'm still confused. I'm still a JSF noob :)
My problem is that whatever I specify in the f:ajax render part isn't the only parts the get "executed". What I mean is, the id specified in render won't get rerendered on screen, but the value of that component do get called.
So:
inputText's f:ajax render=outA event=blur
when blur happens, outA's getter is called and it rerendered, but also the getter of other components are called, but they're not rerendered.
Specifically, in light of the listed code below:
A) When val1 loses focus, it's blur event fires, which has it call getValue1() and rerender outval1. Happy. But, getStuff() is ALSO called (it happens for the other blur and btnCalc also) BUT the result from getStuff() is NOT rendered to tblStuff dataTable.
Why?
How can I fix it, so that on the blur event, only the getters relevent to the render=".." component is executed?
Should I maybe use different sections?
B) when the refresh button is clicked, then it will call getStuff AGAIN, and now show the new dataTable / ie that new data with ALL THE MANY ValueTO's that was added during the blur events and the btnReload click event.
C) For any one event named in A, the getStuff method is called exactly 8 times. ie, click inside inputbox, click outside input box, getStuff() * 8.
Yet, getValue1 is called only twice?
D) Any good JSF2 books out there?
Here is the page:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Stuff</title>
</h:head>
<h:body>
<h:form id="frmTrxMain" prependId="true">
<h1>
Stuff
</h1>
<h:dataTable title="Stuff" id="tblStuff" var="s" value="#{bean.stuff}" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{s.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{s.name}" />
</h:column>
</h:dataTable>
<h:outputText value="No stuff to display" rendered="#{empty bean.stuff}"/>
<h:commandButton value="Refresh" id="btnReload">
<f:ajax render="tblStuff" event="click"/>
</h:commandButton>
<hr/>
<h:panelGrid columns="3" id="pnlTwo">
<h:outputLabel value="Value1"/>
<h:inputText value="#{bean.value1}" id="val1">
<f:ajax event="blur" render="outVal1"/>
</h:inputText>
<h:outputText id="outVal1" value="Entered: #{bean.value1}" />
<h:outputLabel value="Value2"/>
<h:inputText value="#{bean.value2}" id="val2">
<f:ajax event="blur" render="outVal2"/>
</h:inputText>
<h:outputText id="outVal2" value="Entered: #{bean.value2}" />
<h:commandButton value="Calc" id="btnCalc">
<f:ajax event="click" render="outSum"/>
</h:commandButton>
</h:panelGrid>
<h:outputLabel id="outSum" value="#{bean.sum}"/>
</h:form>
</h:body>
</html>
And the backing bean:
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "bean")
#SessionScoped
public class TestStuffBean {
private int id=1;
private String name="a";
//test.xhtml
private String value1;
private String value2;
private List<TestVO> stuff = new ArrayList<TestVO>();
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getSum() {
String result = "";
int sum;
try {
sum = Integer.parseInt(value1) + Integer.parseInt(value2);
result = Integer.toString(sum);
} catch (NumberFormatException e) {
result = "Enter two integers";
}
return result;
}
public List<TestVO> getStuff() {
//the VO is just a POJO with a contructor that takes
//two strings and a getter/setter for each id and name
stuff.add(new TestVO(Integer.toString(id), name+id));
id++;
return stuff;
}
}
I'm not a JSF 2 expert since we're still using 1.2 but I guess they have the same properties here: the getters are called often, e.g. when reconstrucing the view in the restore-view phase. Thus you can't rely on the getters only being called for the actually rendered part. In fact, you shouldn't do any costly operations (like db access) in your getters - in most cases you don't know how often they're actually called in one cycle.
Especially your getStuff() method should be changed, it's also almost always bad design to have a getter cause side effects like something being added to an internal list, like in this case.
Edit: To clarify the comment on getters:
Normally a getter should not do costly operations, since you don't know how often JSF will call them.
Since you still have to get some data from some source (like a database) you might provide methods to only do that (like loadDataFromDB()) and fill some data structure in the managed bean. The getter might then just deliver that data structure.
You might add a check for the data structure not being initialized and if not call the load method in the getter, but I'd only use that as a last option. Generally you should be able to separately call the load method, e.g. by clicking a refresh button or when navigating to the page - that's what we do.