2010-08-04 14 views
6

Die Logik ist, dass der Filter getroffen wird, ist die Bedingung nicht wahr, so dass es durch die Filterkette geht. Nachdem die Antwort festgeschrieben wurde, wird der Filter ausgelöst, und die Bedingung ist nun wahr (ein Anforderungsattribut wurde festgelegt). Es geht um den Forward auszuführen, aber die Seite wird nie weitergeleitet. Ich weiß, dass das etwas damit zu tun hat, dass die Antwort festgeschrieben wird, weil ich verschiedene Logik getestet habe, wo sie weitergeleitet wird, bevor sie zum ersten Mal die Kette trifft, und sie wird erfolgreich weitergeleitet.Ist es möglich, einen Servlet-Filter weiterzuleiten oder umzuleiten, nachdem die Antwort festgeschrieben wurde?

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 

    HttpServletRequest httpServletRequest = (HttpServletRequest)request; 

    if (some condition equals true) { 
     httpServletRequest.getRequestDispatcher("/home.jsp").forward(request, response); 
     return; 
    } else { 
     chain.doFilter(request, response); 
    } 
} 

Beispiel aus meinem Deployment Descriptor:

<filter> 
    <filter-name>MyFilter</filter-name> 
    <filter-class>com.filters.MyFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>MyFilter</filter-name> 
    <url-pattern>*.jsp</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping> 

Antwort

14

Der „committed“ Status eines HttpServletResponse ist wirklich eine Art zu sagen, ob die Antwort-Header haben auf die zugrunde liegenden Socket geschrieben. Bei einer "committed" -Antwort wurde (mindestens) die erste Zeile geschrieben. Da die erste Zeile der Antwort den Statuscode enthält, können Sie den Statuscode einer festgeschriebenen Antwort nicht ändern ... und das bedeutet, dass es zu spät ist, den Status für eine Umleitung in 3xx zu ändern. Ebenso können Sie keine lokale Weiterleitung durchführen, da Sie bereits mit dem Senden der Antwort begonnen haben.

4

Sie können erreichen, was Sie wollen, indem Sie eine benutzerdefinierte HttpServletResponse verwenden. Sie übergeben diese umschlossene HttpServletResponse die Filterkette herunter. Sie können einen lokalen OutputStream bereitstellen, der alle Schreibanforderungen speichert, lokale Variablen, um den Statuscode und die Header zu speichern. Sobald Sie wieder in Ihrem Filter sind, können Sie sich entscheiden, die Umleitung durchzuführen oder die Ergebnisse von den lokalen Variablen aus dem Wrapper in die ursprüngliche ServletResponse zu kopieren (dh den Statuscode und den Header setzen und die Ergebnisse vom lokalen Ausgabestrom in den Antwortstrom der Servlet-Antwort).

Edit:

Siehe den Programming Customized Requests and Responses Abschnitt für ein Codebeispiel, das ein CharResponseWrapper verwendet. In diesem Beispiel wird ein benutzerdefinierter Writer verwendet, der jedoch problemlos auf einen OutputStream erweitert werden kann. Je nachdem, wie Ihr Servlet verwendet wird, müssen Sie eines oder beide von getWriter() und getOutputStream() außer Kraft setzen, um die Übertragung der ursprünglichen Antwort zu verzögern. Außerdem müssen Sie isCommitted() außer Kraft setzen, um false zurückzugeben, so dass die Weiterleitung jederzeit in der Filterkette ausgeführt werden kann. Sie müssen auch resetBuffer() überschreiben, um einen neuen OutputStream/Writer zu initialisieren, um den neuen Inhalt (einschließlich der Header) nach der Weiterleitung/Weiterleitung zu speichern.

+0

Könnten Sie bitte einen 'Beispielcode' basierend auf dem oben gewünschten'/home.jsp'-Redirect bereitstellen? Ich habe auch Probleme mit diesem Problem. Vielen Dank! – DougA

+0

@DougA Überprüfen Sie die Änderungen in meiner Antwort. Das sollte zusammenfassen, was zu tun ist. – shams