How to produce valid HTML with JSPX? (not XHTML)

ooBartez picture ooBartez · Jan 9, 2011 · Viewed 13.1k times · Source

When trying to create a HTML page with JSPX you will face the following difficulties:

  • JSPX minimizes tags we don't want it to, for example <div class="foo"></div> becomes <div class="foo"/> which is interpreted differently by browsers
  • JSPX tags must be closed, while some HTML tags should remain unclosed, for example <script...>. Self-closed <script.../> tag is not recognized by IE and Firefox.
  • Specifying HTML5 doctype (<!DOCTYPE html>)
  • Inline JavaScript

This question is a response to a few other that all boil down to the same problem. I couldn't find a comprehensive answer so I'm posting the result of my findings.

Related questions:

Answer

ooBartez picture ooBartez · Jan 9, 2011

JSPX is perfectly suitable for producing both HTML and XHTML.

It boils down to understanding the XML nature of this language. JSPX is XML while HTML is not. One of the implications is that JSPX parser "minimizes" empty tags because XML does not differentiate between self-closing tags and empty tags. This causes the <script...> and <div></div> tags problems. However, it's worth to note that while JSPX files must be valid XML, the output they produce does not. Thus it's perfectly correct to have a JSPX file producing HTML (not just XHTML). In fact, you could use JSPX to produce any textual output such as CSV, CSS or JS although it would be rather inconvenient.

Taking account of the above, the cleanest solution seems to be creating a custom taglib with tags such as htmlScript, htmlDiv, etc. These tags could be used like this:

<html:div styleClass="foo" selfClosing="false">${message}<html:div>

Its HTML output would contain the closing tag, regardless of the content:

<div style="foo"></div>
<div style="foo">Hello</div>

A taglib like this would let you build HTML pages with JSPX without using rather ugly workarounds.

Building HTML pages seems to be one of the most common application of JSPX. It's somewhat surprising that there's no standard HTML library. JSF has one but if you use clean JSP it won't help you. There might be a third-party library filling this gap but I couldn't find one.

If you don't feel like coding your own taglib, an alternative approach is to use CDATA:

<![CDATA[<script type="text/javascript" src="/js/jquery-1.4.4.min.js">]]>

or:

<![CDATA[<script type="text/javascript" src="/js/jquery-1.4.4.min.js"></script>]]>

Other proposals in the related questions were to put a comment or empty <jsp:text> inside <script> which gives the same result:

<script type="text/javascript" src="/js/jquery-1.4.4.min.js"><!-- Prevent self-closing --></script>

(as Ralph noted, the above doesn't work with WebSphere) or:

<script type="text/javascript" src="/js/jquery-1.4.4.min.js"><jsp:text></jsp:text></script>

CDATA also comes in handy in a few other cases. One of them is printing the HTML5 doctype (<!DOCTYPE html>). JSPX won't let you put DOCTYPE declaration inside your document because it's not a valid XML. JSPX also deifnes the jsp:output tag but it prints the SYSTEM attribute even when it's empty. A workaround is to wrap the DOCTYPE in CDATA at the beginning of a page:

<![CDATA[<!DOCTYPE html>]]>

CDATA can also be used to encapsulate inline JavaScript. While this produces parsing error because of the "<" sign:

<script type="text/javascript">
    var x = 7 < 5;
</script>

this will work fine:

<script type="text/javascript">
    <![CDATA[
    var x = 7 < 5;
    ]]>
</script>

Note that CDATA in JSPX outputs everything as-is but still evaluates EL expressions. Thus the following:

<![CDATA[
<jsp:expression>"asd " + "def"</jsp:expression>
${1 + 2}
]]>

produces:

<jsp:expression>"asd " + "def"</jsp:expression>
3

Hope this helps :)