Hallo,
ich möchte ein JSF-Formular benutzen, um einen neuen Datensatz anzulegen oder einen bestehenden anzuzeigen/ zu bearbeiten. Wird ein Datensatz neu angelegt, so sollen einige Felder des Formulars mit Werten vorbelegt werden. Ich möchte dazu Java EE 6 Techiken (JSF, CDI, EJB, JPA) verwenden, also kein Seam, Spring, etc.
Szenario:
Ich habe die Annotationen [c]@ManagedBean[/c] in Verbindung mit [c]@RequestScoped[/c] und [c]@SessionScoped[/c] verwendet und bin mit beiden nicht zum Ziel gekommen. Für die Vorbelegung der Felder benutze ich eine Methode die ich mit [c]@PostConstruct[/c] annotiere.
Konkrete Fragestellung:
Aufgetretene Probleme mit den Annotationen:
@ViewScoped
Mit @ViewScoped funktioniert alles richtig beim Anlegen eines neuen Datensatzes. Die mit @PostConstruct annotierten Methode wird beim ersten Aufruf des Formulars aufgerufen und die Felder werden korrekt mit Werten vorbelegt. Ändert man nun einige Werte so bleiben diese auch erhalten, wenn das Formular mehrfach wieder aufgerufen wird (z.B. bei Fehleingaben).
Wenn ich allerdings in einer Liste einer anderen JSF-Seite einen Datensatz zum Bearbeiten auswähle, dann werden die Daten nicht in das Formular geladen, da ich ja den Seitenkontext gewechselt habe. Das Objekt wird also neu erzeugt. Statt den ausgewählten Datensatz anzuzeigen, wird ein neues Objekt erstellt.
@RequestScoped
Also habe ich es mit der Annotation @RequestScoped versucht. Nun werden die Daten korrekt im Formular angezeigt, wenn ich in der Liste einen Datensatz zum Bearbeiten ausgewählt habe.
Ändere ich nun allerdings einige dieser Werte und es treten Fehler beim Prüfen des Formulars auf (z.B. bei Fehleingaben) wird die mit @PostConstruct annotierte Methode aufgerufen. Diese füllt dann die Felder mit den Standardwerten, was ja nicht sein soll.
Ich bin ratlos wie ich das korrekt umsetzen soll und bin übrigens Java EE Newbie.
Auszug Formular [license.xhtml]:
[XML]
...
<hutputLabel value="Erstellt am" for="createdAt" />
<h:inputText id="createdAt" value="#{licenseController.license.createdAt}" readonly="true" >
<f:convertDateTime type="date"/>
</h:inputText>
<p:message for="createdAt" />
<hutputLabel value="Erstellt von" for="createdBy" />
<h:inputText id="createdBy" value="#{licenseController.license.createdBy}" readonly="true" />
<p:message for="createdBy" />
</hanelGrid>
</p:fieldset>
<p:commandButton action="#{licenseController.doCreateLicense}" value="Speichern" update="form" />
[/XML]
Auszug Liste (Edit-Button) [licenses.xhtml]:
[XML]
<p:column id="editButton">
<p:commandButton id="edit" action="#{licenseController.doEditLicense}" ajax="false" image="ui-icon ui-icon-search">
<f:setPropertyActionListener value="#{license}" target="#{licenseController.selectedLicense}" />
</p:commandButton>
</p:column>
[/XML]
Auszug LicenseController.java:
Vielen Dank im Voraus für Eure Tipps.
Bastian
ich möchte ein JSF-Formular benutzen, um einen neuen Datensatz anzulegen oder einen bestehenden anzuzeigen/ zu bearbeiten. Wird ein Datensatz neu angelegt, so sollen einige Felder des Formulars mit Werten vorbelegt werden. Ich möchte dazu Java EE 6 Techiken (JSF, CDI, EJB, JPA) verwenden, also kein Seam, Spring, etc.
Szenario:
- Ein JSF-Formular soll zum Anlegen, bzw. Bearbeiten eines Datensatzes verwendet werden.
- Wird ein neuer Datensatz angelegt, so sollen einige Formularfelder mit Werten vorbelegt werden.
- Ändert man einige dieser Werte und kann das Formular nicht gespeichert werden (z.B. wegen fehlerhafter Eingabe) so sollen die eingetragenen Werte erhalten bleiben.
- Wird ein bestehender Datensatz aufgerufen, so sollen die Werte aus der Datenbank angezeigt werden. Die Methode zum Vorbelegen der Felder soll also nicht ausgeführt werden.
Ich habe die Annotationen [c]@ManagedBean[/c] in Verbindung mit [c]@RequestScoped[/c] und [c]@SessionScoped[/c] verwendet und bin mit beiden nicht zum Ziel gekommen. Für die Vorbelegung der Felder benutze ich eine Methode die ich mit [c]@PostConstruct[/c] annotiere.
Konkrete Fragestellung:
- Wie setzt man sowas in EE 6 um (Best Practice)?
- Muss man dafür [c]@ConversationScoped[/c] verwenden, oder macht man das besser anders?
Aufgetretene Probleme mit den Annotationen:
@ViewScoped
Mit @ViewScoped funktioniert alles richtig beim Anlegen eines neuen Datensatzes. Die mit @PostConstruct annotierten Methode wird beim ersten Aufruf des Formulars aufgerufen und die Felder werden korrekt mit Werten vorbelegt. Ändert man nun einige Werte so bleiben diese auch erhalten, wenn das Formular mehrfach wieder aufgerufen wird (z.B. bei Fehleingaben).
Wenn ich allerdings in einer Liste einer anderen JSF-Seite einen Datensatz zum Bearbeiten auswähle, dann werden die Daten nicht in das Formular geladen, da ich ja den Seitenkontext gewechselt habe. Das Objekt wird also neu erzeugt. Statt den ausgewählten Datensatz anzuzeigen, wird ein neues Objekt erstellt.
@RequestScoped
Also habe ich es mit der Annotation @RequestScoped versucht. Nun werden die Daten korrekt im Formular angezeigt, wenn ich in der Liste einen Datensatz zum Bearbeiten ausgewählt habe.
Ändere ich nun allerdings einige dieser Werte und es treten Fehler beim Prüfen des Formulars auf (z.B. bei Fehleingaben) wird die mit @PostConstruct annotierte Methode aufgerufen. Diese füllt dann die Felder mit den Standardwerten, was ja nicht sein soll.
Ich bin ratlos wie ich das korrekt umsetzen soll und bin übrigens Java EE Newbie.
Auszug Formular [license.xhtml]:
[XML]
...
<hutputLabel value="Erstellt am" for="createdAt" />
<h:inputText id="createdAt" value="#{licenseController.license.createdAt}" readonly="true" >
<f:convertDateTime type="date"/>
</h:inputText>
<p:message for="createdAt" />
<hutputLabel value="Erstellt von" for="createdBy" />
<h:inputText id="createdBy" value="#{licenseController.license.createdBy}" readonly="true" />
<p:message for="createdBy" />
</hanelGrid>
</p:fieldset>
<p:commandButton action="#{licenseController.doCreateLicense}" value="Speichern" update="form" />
[/XML]
Auszug Liste (Edit-Button) [licenses.xhtml]:
[XML]
<p:column id="editButton">
<p:commandButton id="edit" action="#{licenseController.doEditLicense}" ajax="false" image="ui-icon ui-icon-search">
<f:setPropertyActionListener value="#{license}" target="#{licenseController.selectedLicense}" />
</p:commandButton>
</p:column>
[/XML]
Auszug LicenseController.java:
Java:
@ManagedBean
@RequestScoped
public class LicenseController implements Serializable {
@EJB
private LicenseEJB licenseEJB;
private License license = new License();
private List<License> licenseList = new ArrayList<License>();
private License selectedLicense;
@PostConstruct
public void doConstruct() {
// DS für Tabelle auslesen
this.licenseList = licenseEJB.findAll();
// Formularfelder vorbelegen
this.license.setRegKey(getRandomKey());
this.license.setCreatedAt(new Date());
this.license.setCreatedBy("Captain Kirk");
this.license.setMaxLicenses(1);
}
public String doCreateLicense() {
this.license = licenseEJB.createLicense(license);
return "licenses.xhtml?faces-redirect=true";
}
public String doEditLicense() {
this.license = this.selectedLicense;
return "license";
}
// ... getter und setter
}
Vielen Dank im Voraus für Eure Tipps.
Bastian