# Back Button bei JSF Anwendung



## Tintenfisch (8. Okt 2022)

Hallo Forum, 

Vorab, es fiel mir auch schon nicht gerade leicht, dieses Problem in Google zu formulieren, deshalb erkläre ich es einfach mal Stück für Stück.
Ich habe eine JSF-Anwendung, welche über ein Template strukturiert ist. Der "Center-Bereich" des Templates, lässt sich über Buttons verändern und zeigt somit unterschiedliche Seiten. 
Das Problem zeigt sich, wenn ich von einer auf die andere Seite wechseln und dann über den Zurück-Button des Browsers, wieder auf die vorherige Seite wollen.  Nach dem click auf den Zurück-Button des Browsers, funktioniert die Seite nicht mehr so, wie sie das ursprünglich tat. Denn sollte ich einen beliebigen Button auf dieser Seite drücken, führt dieser unabhängig von seiner eigentlichen Funktion, zurück auf die Seite, auf der ich vor dem betätigen des Zurück-Buttons des Browsers war.

Ich hoffe, dass damit jemand etwas anfangen kann und wäre um jede Unterstützung dankbar.


----------



## KonradN (8. Okt 2022)

Ich habe mit JSF bisher nicht wirklich Erfahrung gesammelt. Aber das hört sich etwas danach an, dass Du Informationen in der Session hast und nicht auf der Seite. Durch den Zurück Knopf im Browser wechselst Du dann zwar auf der anderen Seite, aber der Session State ist natürlich unverändert.

Evtl. hilft da https://docs.oracle.com/cd/E24290_01/coh.371/e22620/myfaces.htm#COHCW347 etwas weiter - bei JSF kannst Du wohl in der web.xml vorgeben, dass so Informationen auf dem Client gespeichert werden sollen. Dann gehen dann aber auch mehr Daten zwischen Client und Server hin und her - daher aufpassen, was man da alles speichern will!

Und das Umsetzen würde dann per

```
<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>
```
gehen.

Aber schau Dir das im Detail an - denn wie gesagt: Ich habe da keine Erfahrungen und dies kann komplett in die falsche Richtung gehen. Das ist also nicht als Lösung sondern nur als "Recherche-Ansatz" zu verstehen.


----------



## Tintenfisch (13. Okt 2022)

> Aber das hört sich etwas danach an, dass Du Informationen in der Session hast und nicht auf der Seite.


Das ist tatsächlich auch die Ursache des Problems.

Leider habe ich bisher anhand der `javax.faces.STATE_SAVING_METHOD` und einer umstellung auf "client" keinerlei Möglichkeit gefunden, die notwendigen Daten im Cache zu speichern.

Zur Ergänzung der Problembeschreibung:
Das bloße wechseln zwischen den Seiten funktioniert reibungslos. Wird die Seite jedoch über ein Template dagestellt und durch eine Variable eine xhtml Seite eingefügt `<ui:include src="#{myView.contentPage}" />`, kommt es zu dem oben geschilderten Problem. Der Wert, welcher in diesem Fall in der "MyBean" gespeichert ist, wird nach einem Seitenwechsel auf den dementsprechenden Link angepasst. Nun besteht jedoch auch nach dem Drücken auf den Back-Button dieser Wert und nutzt diesen auch nach erneutem Absenden, da der Status der Bean nicht im Cache gespeichert ist.

Der derzeitige Lösungsansatz besteht nun darin, dem Browser über einen Filter zu untersagen, jeglichen Cache der Anwendung zu speichern. Dazu wäre dann bei belieben ein in die Seite integrierter Back-Button denkbar.
Zum Filter mal der entsprechende Code:

```
package listeners;

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletResponse;

public class CacheControlPhaseListener implements PhaseListener {

    @Override
    public void afterPhase(PhaseEvent arg0) {
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
        response.addHeader("Pragma", "no-cache"); // HTTP 1.0
        response.addHeader("Cache-Control", "no-cache"); // HTTP 1.1
        response.addHeader("Cache-Control", "no-store"); // HTTP 1.1
        response.addHeader("Cache-Control", "must-revalidate"); // HTTP 1.1
        response.addHeader("Expires", "0"); // Proxies  
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }
}
```


```
<lifecycle>
    <phase-listener id = "nocache">listeners.CacheControlPhaseListener</phase-listener>
</lifecycle>
```


----------

