I get a error: Conversion error:
{0}: Conversion error occurred.
when try to display O value in Primefaces knob component. I already changed input value types to: integer, String, Double and this did not help. I also tried to build a converter, but this component did not use it. I do not have any idea what do with this. I have no idea how to solve this problem.
<p:knob value="#{res.completionValue}" width="50" height="50" disabled="true" converter="knobConverter" />
Converter:
#FacesConverter("knobConverter")
public class KnobConverter implements Converter {
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
Integer returnValue;
if(value != null && value.trim().length() >0) {
try{
returnValue = (ing) value;
}
catch(NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid theme."));
}}
return returnValue;
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null) {
return String.valueOf((object));
}
else {
return null;
}
}
}
I deleted the entire class and recreated it (return Integer values, do no use Converter). Now it work correct, generally I do not have any idea what was the reason.
Related
This can be seen as a continuation of my other question.
In my backend view, I have a list of some POJO. The POJO is converted to JSON with its toString() method:
BackingView.java
#Getter #Setter private List<SomePOJO> pojoList = ...
SomePojo.java
#EqualsAndHashCode(callSuper = false, of = {"id"})
public class SomePOJO implements Serializable {
private static final long serialVersionUID = 1L;
#Getter #Setter private Long id;
#Getter #Setter private Long date;
#Getter #Setter private Date name;
....
#Override
public String toString() {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(this);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
//making a readable string-representation of the object to display on the orderList
public String toStringOrderlistDisplay() {
return "Pojo with id " + id + "and so on... "
}
In my frontend, I want to allow the user to sort this pojo-list using Primefaces orderList :
<p:orderList id="ordList" widgetVar="ordList"
value="#{backingview.pojoList }" var="rfg"
controlsLocation="left" responsive="true" itemValue="#{rfg}"
itemLabel="#{rfg.toStringOrderlistDisplay()}" converter="#{pojoConverter}">
</p:orderList>
PojoConverter.java
#Named
#FacesConverter(value = "pojoConverter")
public class PojoConverter implements Converter {
#Override
public Pojo getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(value, RechtsaktFallgeschichte.class);
}
catch (NumberFormatException | IOException ex) {
ex.printStackTrace();
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid Pojo."));
}
}
else { return null; }
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
SomePOJO r = (SomePOJO) value;
if (r != null) {
return r.toString();
}
else { return null; }
}
}
Converting to JSON seems to work just fine, if I print the output of the getAsString() method, everything looks as you would expect. However, when the getAsObject() method is called, the value-String-parameter always contains "[object Object]" instead of the POJOs JSON representation. What am I doing wrong here?
I don't know if it is possible to achieve what you are trying to do, but a better way (and the working one) is to pass the POJO id in the getAsString() method, and convert it back to Pojo using a cache map Map<Long, Pojo> pojoCache.
The converter should look like this:
PojoConverter.java
#Named
#FacesConverter(value = "pojoConverter")
public class PojoConverter implements Converter<Pojo> {
#Inject
private PojoService pojoService;
#Override
public Pojo getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
return pojoService.getPojoCache().get(Long.valueOf(value));
} else {
return null;
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Pojo value) {
if (value != null) {
return String.valueOf(value.getId());
} else {
return null;
}}
}
For a more detailed explanation check this: p:orderList converter getAsObject() doesn't call Object.toString()
Sorry for my bad english.
I try to show a selectOneMenu using converter but throws error:
java.lang.Integer cannot be cast to pojos.HoraRango
java.lang.ClassCastException: java.lang.Integer cannot be cast to pojos.HoraRango
at managedBeans.HoraRangoConverter.getAsString(HoraRangoConverter.java:46)
at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:114)
at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:61)
at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeLabel(SelectOneMenuRenderer.java:202)
at or
my xhtml
<p:outputLabel for="console" value="Basic:" />
<p:selectOneMenu id="console" value="#{bPistasDisponibles.inicioHoraElegido}" style="width:125px" converter="HoraRangoConverter">
<f:selectItems value="#{bPistasDisponibles.inicioHora}" var="inicioHora"
itemLabel="#{inicioHora.hora}" itemValue="#{inicioHora}" />
</p:selectOneMenu>
my converter
public class HoraRangoConverter implements Converter{
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value != null && value.trim().length() > 0) {
try {
DaoHoraRango daohoraRango = new DaoImplHoraRango();
HoraRango cat= daohoraRango.verHoraRango(Integer.parseInt(value));
return cat;
} catch(NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid Cine."));
}
}
else {
return null;
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value != null) {
return String.valueOf(((HoraRango)value).getIdHoraRango());
}
else {
return null;
}
}
}
Thanks
I'm trying to apply a JSF converter to an Entity inside a selectOneMenu,
but the converter is not recognized, I get this warning in my xhtml file,
<<"nomProjet" cannot be resolved>>
and when I run the application I'm getting Error HTTP 500 :
itemLabel="#{projet.nomProjet}": Property 'nomProjet' not found on type java.lang.String
Here is my code:
The selectOneMenu in my view
<p:selectOneMenu id="projet" converter="projetConverter" value="# {affectation.selectedProjet}" >
<f:selectItems var="projet" itemValue="#{projet}" itemLabel="#{projet.nomProjet}" value="#{affectation.projetsAffectablesCollaborateur()}" />
</p:selectOneMenu>
The converter
#Component
#FacesConverter("projetConverter")
public class ProjetConverter implements Converter {
#Autowired
private ProjetRepository projetRepository;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value == null || value.isEmpty()) {
return null;
}
try {
Projet projet = projetRepository.findByIdProjet(Long.valueOf(value));
return projet;
} catch (NumberFormatException exception) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur de conversion", "ID de projet invalide"));
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
if (value instanceof Projet) {
return String.valueOf(((Projet) value).getIdProjet());
} else {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur de conversion", "Instance de projet invalide"));
}
}
}
And my Entity :
#Entity
#NamedQuery(name = "Projet.findAll", query = "SELECT p FROM Projet p")
public class Projet implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long idProjet;
private String nomProjet;
#Transient
private List<Role> listRoles = new ArrayList<Role>();
public List<Role> getListRoles() {
return listRoles;
}
public void setListRoles(List<Role> listRoles) {
this.listRoles = listRoles;
}
// bi-directional many-to-one association to AffectationProjetRole
#OneToMany(mappedBy = "projet")
private List<AffectationProjetRole> affectationProjetRoles;
public Projet() {
}
public Projet(String nomProjet) {
this.nomProjet = nomProjet;
}
public long getIdProjet() {
return this.idProjet;
}
public void setIdProjet(long idProjet) {
this.idProjet = idProjet;
}
public String getNomProjet() {
return this.nomProjet;
}
public void setNomProjet(String nomProjet) {
this.nomProjet = nomProjet;
}
public List<AffectationProjetRole> getAffectationProjetRoles() {
return this.affectationProjetRoles;
}
public void setAffectationProjetRoles(List<AffectationProjetRole> affectationProjetRoles) {
this.affectationProjetRoles = affectationProjetRoles;
}
public AffectationProjetRole addAffectationProjetRole(AffectationProjetRole affectationProjetRole) {
getAffectationProjetRoles().add(affectationProjetRole);
affectationProjetRole.setProjet(this);
return affectationProjetRole;
}
public AffectationProjetRole removeAffectationProjetRole(AffectationProjetRole affectationProjetRole) {
getAffectationProjetRoles().remove(affectationProjetRole);
affectationProjetRole.setProjet(null);
return affectationProjetRole;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (idProjet ^ (idProjet >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Projet other = (Projet) obj;
if (idProjet != other.idProjet)
return false;
return true;
}
}
How is this caused and how can I solve it?
itemLabel="#{projet.nomProjet}": Property 'nomProjet' not found on type java.lang.String
This error message tells that #{projet} is during runtime actually a java.lang.String. Let's look where's #{projet} is coming from.
<f:selectItems value="#{affectation.projetsAffectablesCollaborateur()}"
var="projet" itemValue="#{projet}" itemLabel="#{projet.nomProjet}" />
Thus, #{affectation.projetsAffectablesCollaborateur()} actually returned a List<String>. If this is unexpected, then beware of generic type erasure and doublecheck all unchecked casts that the generic type is not incorrectly assumed. Generally, the mistake is in the persitence layer. For example, when you mistakenly execute the query SELECT p.nomProject FROM Project p instead of SELECT p FROM Project p and then performed an unchecked cast against List<Projet> instead of List<String>.
Do note that rendering item labels doesn't involve the converter at all, so showing and blaming it is unnecessary. The converter is only used on item values.
I have a converter as follows to trim all leading and trailing white spaces and strip additional spaces between words.
#ManagedBean
#ApplicationScoped
#FacesConverter(forClass=String.class)
public final class StringTrimmer implements Converter
{
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
return value != null ? value.trim().replaceAll("\\s+", " ") : null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
return value!=null ? ((String) value).trim().replaceAll("\\s+", " ") : null;
}
}
This converter is applied globally to all string type properties in associated backing beans.
Sometimes it is necessary to bypass this converter for certain properties like "password" in which no white spaces or additional spaces between words should be trimmed or striped respectively.
How can such string type properties be bypassed so that this converter is not applied to them?
Several ways.
Explicitly declare a converter which does effectively nothing with the value.
E.g.
<h:inputSecret ... converter="noConverter" />
with
#FacesConverter("noConverter")
public class NoConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return value;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return (value != null) ? value.toString() : ""; // This is what EL would do "under the covers" when there's no converter.
}
}
Pass an additional component attribute and let the converter check that.
<h:inputSecret ...>
<f:attribute name="skipConverter" value="true" />
</h:inputSecret>
with
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (Boolean.valueOf(String.valueOf(component.getAttributes().get("skipConverter")))) {
return value;
}
// Original code here.
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (Boolean.valueOf(String.valueOf(component.getAttributes().get("skipConverter")))) {
return (value != null) ? value.toString() : "";
}
// Original code here.
}
Let the converter check the component type. The UIComponent behind <h:inputSecret> is an instance of the HtmlInputSecret class.
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (component instanceof HtmlInputSecret) {
return value;
}
// Original code here.
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (component instanceof HtmlInputSecret) {
return (value != null) ? value.toString() : "";
}
// Original code here.
}
Which way to use depends on business requirements and degree of reusability of the converter.
i'm facing a problem with a Converter. In my xhtml file, i have a selectOneMenu with a list of object and i want to set an object in my managedBean.
If my managedBean has #SessionScoped, the object in the managedbean is filled but if the managedeban has #ViewScoped, the converter is never use and my object is null.
how to fix this problem ?
Xhtml :
<p:selectOneMenu value="#{rechercheBean.role}" converter="#{typConverter}">
<f:selectItems id="item" value="#{typBean.roles}" var="r" itemLabel="#{r.valeur}" itemValue="#{r}" />
</p:selectOneMenu>
typConverter :
public class TypConverter implements Converter{
#EJB
private TypFacadeLocal TypBean;
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
if (submittedValue.trim().equals("")) {
return null;
}
else {
try {
Integer id = Integer.parseInt(submittedValue);
Typ typ = new Typ();
typ = TypBean.find(id);
return typ;
}
catch (NumberFormatException exception) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Typ non valide"));
}
}
}
public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
if (value == null || value.equals("")) {
return "";
}
else {
return String.valueOf(((Typ) value).getId());
}
}
}
Tx a lot
The problem is the component c:when. With the attribut renderer of the component , there is no problem.