Response Header Änderung nach RequestDispatcher include

Guten Morgen,

Aus javadoc zum include im RequestDispatcher:

The included servlet cannot change the response status code or set headers;
any attempt to make a change is ignored.

Ich habe aktuell den Fall dass in einem Servlet eine jsp per include aufgerufen wird. Diese JSP setzt in der Response Header Informationen und der Client erhält diese auch.

Liegt hier ein Verständnisproblem bzgl. der javadoc meinerseits vor?

Vielen Dank für Tipps, LG

Genauer lesen :wink:

cannot change…

d.h. Header und Status dürfen nur einmal gesetzt werden.

[quote=Heady86]Diese JSP setzt in der Response Header Informationen und der Client erhält diese auch.[/quote]Sind diese Informationen

[quote=Heady86;120331]status code or set headers;[/quote]?

bye
TT

Nein, eigentlich sollte nur die Ausgabe in den Ausgabestrom des Servlets geschrieben werden, laut Doku sollte alle HTTP-Header Infos verworfen werden.

Klingt komisch.

machst du wirklich im Servlet ein getServletContext().getRequestDispatcher("TEST").include(request, response)

und in der jsp ein


<% 
      response.setContentType("application/whatever"); 
      response.setHeader("Schmarrn","zonk=7" ); 
%>

Hi,

Im Servlet:

disp = request.getRequestDispatcher(-- Resource jsp auflösen --);
response.setHeader("testheader", "INIT");
disp.include(request, response);

In der jsp:
response.setHeader("testheader","CHANGED");

In Firebug Antwort Header:


HTTP/1.1 200 OK
Last-Modified: Fri, 17 Jul 2015 07:27:41 GMT
testheader: CHANGE
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Server: Jetty(7.6.13.v20130916)

Grüße

*** Edit ***

Hi,

kleiner Zusatz:
Gilt diese Einschränkung vielleicht nur für Standardheader wie z.B. “Content-Type” usw.? Diesen könnte ich nämlich nach dem include nicht mehr überschreiben, meine eigenen allerdings schon.

Danke für eure Hilfe. Viele Grüße

was heißt ‚könnte‘? hast du dazu konkret getestet, macht der String „testheader“ oder anderes einen reproduzierbaren Unterschied?

hast du eigentlich nur ein Hauptservlet dass selber keinen Content schreibt, zumindest nichts vor dem include()?

die Frage ob man solche Stati noch setzen kann, nachdem schon etwas geschrieben, spielt vielleicht wie so oft eine Rolle,
vielleicht ist die API da ungenau und geht von bereits ausgegebenen HTML aus (warum auch sonst include :slight_smile: ), obwohl eigentlich sehr überzeugt geschrieben…

macht Einfügung von nur wenig HTML, welches dann vielleicht geflusht wird, bereits einen Unterschied?

Hans’s Top Ten JSP Tips - O’Reilly Media

An HTTP response message contains both headers and a body. […] All response headers must be sent to the browser before the body is sent.
[…] To allow parts of the body to be produced (from static template text as well as content generated dynamically by JSP elements) before headers are set, the body is buffered. […]
In most cases, this is not a problem. The default buffer size is 8KB […] But if you use the include action in a page, you may be in for a surprise. Due to limitations in the way the servlet features used by jsp:include are specified, the buffer is always flushed before the target page is invoked. This means that you can’t set headers or use jsp:forward after a jsp:include action.

was alles freilich nichts zu RequestDispatcher.include() aussagt, aber noch zwischen ‚include directive‘ und ‚include action‘ in der JSP unterscheidet, kompliziert genug

aber entweder wird sich darauf bezogen und ohne Content before ist auch ein include() evtl. noch voll funktionsfähig,
oder das RequestDispatcher.include() müsste abweichend irgendeinen Status setzen dass die Aktionen verboten/ wirkungslos sind?
lohnt wohl nicht

Hm, tomcat 8.0.3 macht es “richtig”,

könnte eine Ungenauigkeit in der Implementierung von Jetty sein?

Hi,

Hast du eigentlich nur ein Hauptservlet dass selber keinen Content schreibt, zumindest nichts vor dem include()?

Das dürfte der entscheidende Punkt sein. Ich habe ein Servlet welches den Request analysiert und auf Basis dieser Analyse das entsprechende Template per RequestDispatcher include aufruft. Hier lande ich dann in einer Haupt JSP in welcher ich ganz oben diese Header setze.
Zu diesem Zeitpunkt wurde also noch nichts rausgeschickt.

Was z.B. NICHT mehr funktioniert ist:


response.setHeader("bin_da", "ja");
response.setHeader("ich_auch", "ja");
out.print("schreib was raus");
out.flush();
response.setHeader("ich_nicht_mehr", "nein");

Ein AutoFlush weil der Buffer voll ist dürfte uns in diesem Fall auch nicht in die Quere kommen da es wie gesagt die erste Position in der obersten JSP ist, von daher würde ich das als legitim bezeichnen es so zu machen. Einwände?

Vielen Dank für eure Hilfe und viele Grüße

wer weiß a la @Bleiglanz Post, ob in allen Servern funktionierend

und nun natürlich die nötige Hauptfrage:
ist dir bewußt, was RequestDispatcher.forward() ist?
damit kann man auf ein Haupt-JSP leiten und dann sollte es auch noch garantiert funktionieren

ist dir bewußt, was RequestDispatcher.forward() ist?
damit kann man auf ein Haupt-JSP leiten und dann sollte es auch noch garantiert funktionieren

forward hab ich als erstes benutzt, hier gabs aber eine fiese Falle in Verbindung mit einem eingesetzten Framework. In einem speziellen Fall hab ich bereits im Servlet ein Cacheheader gesetzt, welcher aber später nicht mehr da war. Analyse ergab dass forward als erstes ein „response.resetBuffer();“ aufruft. Der spezifische Request des Framworks und damit verbundene Implementierung hat bei resetBuffer nicht nur einen reset ausgeführt (was im Falle von forward ja ok wäre), sondern gleichzeitig einen flush angestoßen und somit gesetzte Header verworfen, daher der Umstieg auf include was für meinen Anwendungsfall und Anforderung so ausreichend ist.

Danke und Grüße

auf eine Möglichkeit noch hingewiesen, auf die ich vorhin bei Suche gestoßen bin,
selber nicht mehr so fit darin, so dass ich es auch nicht ganz überblicke:

java - Using sendRedirect inside a servlet forwarded with request dispatcher - Stack Overflow
Tenor: Header als Attribute im Request oder intern merken,
nach aller variabler Arbeit einen Filter um Eintragung in Response kümmern lassen, was anscheinend noch funktionieren soll

java - Using sendRedirect inside a servlet forwarded with request dispatcher - Stack Overflow
Tenor: Header als Attribute im Request oder intern merken, nach aller variabler Arbeit einen Filter darum kümmern lassen

Danke für den Link. Genau das war unsere Alternative :slight_smile: . Der Header via JSP Ansatz war so gesehen der erste proof of concept, sauberer ist es auf jedenfall das ganze durch einen eigenen Service füllen zu lassen. JSP Ansatz hatte zusätzlich den Charme dynamisch Änderungen vornehmen zu können. → keine Javacodeänderungen und damit verbundene Integrationszyklen.

Für mich soweit gelöst, euch allen ein schönes Wochenende