views:

197

answers:

4

What happens when headers are repeated in a .jsp you include in another .jsp?

For example if example.jsp starts with this:

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page"&gt;
<jsp:directive.page contentType="text/html; charset=UTF-8" />

<div class="content">

<jsp:include page="support.jsp"/>
...

(it includes support.jsp)

And then support.jsp starts also with this:

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page"&gt;
<jsp:directive.page contentType="text/html; charset=UTF-8" />
... 

Is that a problem? Is it bad practice?

What does concretely happen when you repeat several times a header that only corresponds to one header in the resulting .html page?

+1  A: 

It's absolutely normal practice.

What you call 'headers' are just directives to jsp-compiler.

Roman
@Roman: +1 but what I call "header" is also called a "header" in the official JSP specification quoted by axtavt ;)
Webinator
+3  A: 

It's not good practice. If the container has not yet committed the response (i.e. sent anything from the body of the response to the client) it will work, and overwrite whatever the container is preparing to send to the client when it first flushes. However if it has been committed, this will result in an exception. (Or should.)

EDIT: I think I may wrong. Answer above makes a good point -- it's not the same as setting a heaer directly.

Sean Owen
+2  A: 

From JSP Specification:

JSP.5.4 <jsp:include>

...

An included page cannot change the response status code or set headers. This precludes invoking methods like setCookie. Attempts to invoke these methods will be ignored. The constraint is equivalent to the one imposed on the include method of the RequestDispatcher class.

That is, attempt to set content type will be ignored.

axtavt
+1  A: 

The directive is translated directly to ServletResponse.setContentType call

The documentations for this method says:

Sets the content type of the response being sent to the client, if the response has not been committed yet. The given content type may include a character encoding specification, for example, text/html;charset=UTF-8. The response's character encoding is only set from the given content type if this method is called before getWriter is called.

This method may be called repeatedly to change content type and character encoding. This method has no effect if called after the response has been committed. It does not set the response's character encoding if it is called after getWriter has been called or after the response has been committed.

Containers must communicate the content type and the character encoding used for the servlet response's writer to the client if the protocol provides a way for doing so. In the case of HTTP, the Content-Type header is used.

It seems to me that it's better to use this directive only once in the top-level JSP page, maybe even in controller servlet, but definitely not in included pages.

For pages not written in JSPX, one directive that IS useful and should be set in all JSPs that have non-ascii characters is <%@ page pageEncoding="XXXX" %>. I highly recommend it if you don't like to print \uXXXX codes all over your pages.

Alexander Pogrebnyak
However, the OP is using JSPX (JSP XML, JSP in XML syntax, "JSP document"). The XML declaration already includes the page encoding.
BalusC
@BalusC: Thanks for pointing this out. Updated language of the last paragraph. I think the original confusion and proliferation of `contentType` directive stems from not understanding how these 2 totally separate directives work. Basically if your JSP page does have non-ASCII, it is required to set `pageEncoding`, but you should leave `contentType` to somebody higher in the chain. At least that was my own confusion.
Alexander Pogrebnyak
@Alexander Pogrebnyak: I gave you +1 but... You did not really address the question I think: the JLS that axtavt quoted specifically states that *"An included page cannot change the response status code or set headers. Attempts to invoke these methods will be ignored"*. So AFAICT I'm doing an include and hence the later calls are going to be ignored. This is not the same as what you quoted, which deals specifically with the *setContentType* method (apparently when *not* called from inside an "included" .jsp).
Webinator