JSF String cannot be cast to javax.faces.model.SelectItem

jimmykimmy

Mitglied
Hallo, ich sitze seit 4 Stunden an einem Problem und weiß einfach nicht mehr weiter.

Ich möchte auf einer Seite Checkboxen anzeigen lassen. Das klappt auch wunderbar. Nach dem "abschicken" des Forms, wird eine Funktion "anzeigen" aufgerufen. Diese soll die angekreuzten Checkbox-Werte wiedergeben (also: was wurde angekreuzt).
Ich bekomme allerdings IMMER die Fehlermeldung: java.lang.String cannot be cast to javax.faces.model.SelectItem

Mein Code sieht wie folgt aus:

index.xhtml:
HTML:
<h:selectManyCheckbox id="nase" value="#{controller.selectItems}">
      <f:selectItems value="#{controller.selectItemsList}" />
</h:selectManyCheckbox>

Controller.java
Java:
public class MitarbeiterController implements Serializable {
    private List<SelectItem> selectItemsList = new ArrayList<SelectItem>();
    private List<SelectItem> selectItems = new ArrayList<SelectItem>();

    ....

    public void setSelectItemsList() {
        Raum obj1 = new Raum();
        Raum obj1 = new Raum();
        Raum obj1 = new Raum();
        selectItemsList.add( new SelectItem( obj1 ) );
        selectItemsList.add( new SelectItem( obj2 ) );
        selectItemsList.add( new SelectItem( obj3 ) );
    }

    public List<SelectItem>getSelectItemsList() {
        return selectItemsList;
    }

    public List<SelectItem> getSelectItems() {
        return selectItems;
    }

    public void setSelectItems(List<SelectItem> e) {
        selectItems = e;
    }

    ...

    public void anzeigen() {
        // die 3 Varianten bringen alle den selben Fehler!
        String str = getSelectItems().get(0).getLabel();  // var 1
        Raum str = (Raum) getSelectItems().get(0).getValue();  // var 2
        String str = getSelectItems().get(0).getValue().toString();  // var 3
        System.out.println("getSelectItems(): " + str);
        // System.out.println( getSelectItems().get(0) ) ruft die toString Methode meines Objekts korrekt auf. Die Daten liegen also korrekt in "selectItems" vor.
    }
}

ich weiß einfach nicht mehr weiter .... :-(
 
Zuletzt bearbeitet von einem Moderator:

jimmykimmy

Mitglied
Von Convertern habe ich auf meiner Suche auch schon etwas gelesen.
Kannst du mir da genauer erklären, wie man da vorgeht? Oder ist das eine größere Aktion?
 

jimmykimmy

Mitglied
Hmm ich habe nun mal einen Converter geschrieben, aber wie greift der? Wie wende ich ihn an? Sorry, aber weiß derzeit absolut nicht, was ich machen muss, daher bin ich bei deinem Link auch noch etwas überfragt :-/

Wieso kann man denn nicht stinknormal den Wert einer Checkbox auslesen? :-(
 

nocturne

Bekanntes Mitglied
Das ist Konfigurationsaufgabe.
Deine WEB-INF/faces-config.xml müsste so starten:
[XML]<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<converter>
<converter-id>stringConverter</converter-id>
<converter-class>de.deinunternehmen.converter.StringConverter</converter-class>
</converter> ...[/XML]

Deine Klasse StringConverter leitet dann von "javax.faces.convert.Converter" ab und implementiert die Methoden.




Einfach auslesen? JSF ist die Weiterentwicklung von "Einfach". Bei Betrachtung im professionellen Umfeld wirst du die Vorzüge zu schätzen wissen.
 
Zuletzt bearbeitet:

jimmykimmy

Mitglied
Bei mir existierte noch keine "faces-config.xml"-Datei, daher habe ich sie mit folgendem Inhalt angelegt

[XML]<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<converter>
<converter-id>RaumConverter</converter-id>
<converter-class>Converter.Raumconverter</converter-class>
</converter>
</faces-config>[/XML]

Danach bekam ich beim starten nur eine leere weiße Seite im Browser zu sehen.

Ist es korrekt, dass ich die "selectItems" um den Converter erweitere?
HTML:
<f:selectItems value="#{mitarbeitercontroller.selectItemsList}" var="item" itemValue="#{item.id}">
                    <f:converter converterId="Converter.RaumConverter" />
                </f:selectItems>
 

waldek87

Mitglied
Versuch mal die SelectItems mit dem dazugehörigen Constructor anzulegen:
Java:
SelectItem item = new SelectItem(String key, String description);
 

jimmykimmy

Mitglied
Ich bin ein Stückchen weiter. Ich habe folgenden Converter geschrieben:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import Entities.Raum;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;

@FacesConverter("Converter.RaumConverter")
public class RaumConverter implements Converter {

    public Object getAsObject(FacesContext ctx, UIComponent uiComponent, String value) {
        Raum raum = new Raum();
        raum.setId(Integer.valueOf(getProperty(value, "id")));
        raum.setRoomName(getProperty(value, "roomName"));
        raum.setBuildingName(getProperty(value, "buildingName"));
        System.out.println("Converter-> Raum: " + raum);
        System.out.println("Converter-> value: " + value);
        return raum;
    }

    private String getProperty(String source, String propName) {
        int idIndex = source.indexOf(propName + "=") + propName.length() + 1;
        int commaIndex = source.indexOf(",", idIndex);
        if (commaIndex < 0) {
            commaIndex = source.indexOf("]");
        }
        //System.out.println(idIndex);
        //System.out.println(commaIndex);
        //System.out.println("getProperty(): " + source.substring(idIndex, commaIndex));
        return source.substring(idIndex, commaIndex);
    }

    public String getAsString(FacesContext ctx, UIComponent uiComponent, Object value) {
        if (!(value instanceof Raum)) {
            throw new ConverterException();
        }
        Raum raum = (Raum) value;
        StringBuffer stringValue = new StringBuffer("[id=");
        stringValue.append(raum.getId());
        stringValue.append(",roomName=");
        stringValue.append(raum.getRoomName());
        stringValue.append(",buildingName=");
        stringValue.append(raum.getBuildingName());
        stringValue.append("]");
        System.out.println("getAsString(): " + stringValue.toString());
        return stringValue.toString();
    }
}

und ihn der der xhtml-Datei so eingebunden:
HTML:
<h:selectManyCheckbox id="nase" converter="Converter.RaumConverter" value="#{controller.selectItems}">
                <f:selectItems value="#{controller.selectItemsList}" var="item" itemValue="#{item}" />
            </h:selectManyCheckbox>

Wenn ich nun auf "ABSCHICKEN" drücke, wird das Formular jedoch nicht abgeschickt, da eine Meldung unterhalb meines Formulars erscheint:

startseite:nase: Validierungs-Fehler: Wert nicht gültig.

Wieso Validiert er da nun falsch? Die System.out.println()-Befehle geben mir korrekte Daten aus, daher gehe ich davon aus, dass ich innerhalb der Converter-Funktionen korrekt arbeite ...

Ich habe irgendwo gelesen, dass "irgendwo eine equals-Methode fehlt". Ich weißt leider nicht genau, was damit gemeint ist.
 

jimmykimmy

Mitglied
Hab herausgefunden, dass ich die Methode "equals" in meiner Raum-Klasse überschreiben muss, damit nicht mehr städnig "false" geworfen wird. Nun wird das Formular abgeschickt, aber ich bekomme wieder einen Fehler:
Diesmal kann er "Raum" nicht nach "ItemSelect" konvertieren.
Ich flippe bald aus. Ich möchte doch einfach nur die angehakten Checkboxen auswerten :-(
 

JimPanse

Bekanntes Mitglied
Hi,

schau dir das Bsp an (wichtig equals-Methode überschreiben wird in UIComponent aufgerufen):

The BalusC Code: Objects in h:selectOneMenu


In Endeffekt müßtest du die Liste so befühlen :

Java:
new SelectItem(raum.getId(),raum);

in der Methode:

Java:
getAsString(..,...,Obect o){
return ((Raum)o).getRoomName();

und im

Java:
getAsObject(...,...,String value){
long id = Long.valueOf(value);

// hier mit der Id das entsprechende Raum Objekt laden
// entweder aus einer DAO-Klasse oder aus einer ManagedBean, die die Liste hält

// fertig
return raum;
}

Eigentlich verzichtet man drauf Objekte in SelectItems zu packen besser wäre

Java:
new SelectItem(raum.getId(),raum.getRoomName());

und später in der entsprechenden Action-Methode den ausgewählten Raum über id laden.

Grüße
 

jimmykimmy

Mitglied
Danke!
Ich habe es nun ohne Objekte gemacht und nun läuft es.
Dachte es wäre schöner, wenn man das ganze Objekt zur Verfügung hat, aber wenn die ID reicht und es auch legitim ist, über diese ID später nochmal ne Abfrage zu starten, dann umso besser :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Probleme mit Java + Tomcat | Cannot switch on a value of type String for source level below 1.7 Web Tier 8
R Servlet Fetch API gibt einen leeren String aus Web Tier 6
R JSP JSTL <x:if> <c:if> string vergleichen Web Tier 2
A JSF String wird nicht angezeigt Web Tier 2
M JSF Converter für String to List<String> Web Tier 2
K JSP String[] Array nach Javascript Web Tier 4
B String aufteilen und in Variablen speichern. Web Tier 18
LadyMilka java.lang.NumberFormatException: For input string: ... Web Tier 5
B JSF --- Expression mit String.length() Web Tier 2
I JSF: String abschneiden, wenn zu lang Web Tier 2
J JSF Custom Component ValueExpression wird nur als String erkannt Web Tier 2
ruutaiokwu Wert hinter JSP-Tag nach Java-String in Skriptlet Web Tier 4
W List queryForList(String sql, Class element) Web Tier 4
leifg Parameter für Tags aus String lesen (JSP 1.2) Web Tier 2
S JSF HandleRenderException: Cannot add the same component twice bei start von Tomcat7 Web Tier 4
H JSP Wieder einmal: cannot be resolved to a type Web Tier 4
G cannot be resolved to a type - jsp Web Tier 3
B JSF Mojarra 2.1.5: java.lang.IllegalStateException: Cannot create a session after the response has been Web Tier 7
I cannot find FacesContext in Eclipse-JSF1.2 mit JBoss Web Tier 8
B Cannot add or update a child row - javax.persistence.OneToOne Web Tier 13
N JSP org.apache.tomcat cannot be resolved to a type InstanceManager cannot be resolved to a type Web Tier 4
P ResourceBundles - "... cannot be resolved" Web Tier 6
S Attribute einer HttpSession / unchecked cast Web Tier 8
N Cast selectItem zu Entity Web Tier 13

Ähnliche Java Themen

Neue Themen


Oben