20050323 Wednesday March 23, 2005

Trim Spaces in your JSP's HTML One of the annoying things about JSPs is all of the dynamic (non-rendered) parts of the page still produce line breaks. This means that if you do a view-source, you'll likely see large blocks of whitespace.

The good news is you can get rid of this whitespace if you're using Tomcat 5.5.x. Just locate the "jsp" servlet in $CATALINA_HOME/conf/web.xml and add the following <init-param>:

    <init-param>
        <param-name>trimSpaces</param-name>
        <param-value>true</param-value>
    </init-param>

I tested it and it works great. This begs the question - why isn't this on by default? Source: Struts Mailing List.

Update: JSP 2.1 adds the ability to trim whitespaces. Posted in Java at Mar 23 2005, 10:24:58 PM MST 31 Comments

Comments:

On an older version of browsers, whitespaces affects the way a table is rendered. Tidying the HTML might actually cause difference in layout. My question is why Tomcat 5.5 has the feature? What's the reason that pushes it?

Posted by Jason Barker on March 23, 2005 at 11:27 PM MST #

This works in tomcat 5.0.x too. But it has one disadvantage - it removes all whitespace between two JSP tags, even when you might one one space. For example, something like <c:out value="Hello"/> <c:out value="${name}"/> will now say, "HelloMatt". It's the thought of searching through all my JSPs for these types of problems which has put me off using it. Oh, the jasper ant task has a flag to do the same thing if you pre-compile your JSPs...

Posted by Kris on March 24, 2005 at 12:08 AM MST #

Darn - should have escaped my XML. That should have read: Something like <c:out value="Hello"/> <c:out value="${name}/> will now say, "HelloMatt"

Posted by Kris on March 24, 2005 at 12:09 AM MST #

I've been wondering why the JSP compiler creates whitespace for years. I don't understand why it has to create whitespace. There's absolutely no good reason for it.

Posted by Larry Williams on March 24, 2005 at 12:59 AM MST #

if you want to get rid of really ALL whitespaces (not just between directives) try this in your build file:

    <!-- Strip whitespace -->
    <replaceregexp match="&amp;gt;\s*&amp;lt;" replace="&amp;gt;&amp;lt;" flags="g" byline="false">
      <fileset dir="${build.home}" includes="**/*.html,**/*.htm,**/*.jsp,**/*.tag"/>
    </replaceregexp>

this will reduce your pages from 10% to 50%, depending on the content (big savings for tables with many rows)

Posted by Yann Cebron on March 24, 2005 at 01:54 AM MST #

<quote>"I've been wondering why the JSP compiler creates whitespace"<quote>

The JSP compiler doesn't *create* the whitespace. The whitespace already exists in the source document and the JSP compiler just doesn't remove it (Why would it? The whitespace is outside any JSP tags). If you remove the line breaks between JSP tags then there will be none in the generated HTML.

Not this

<%@ page import="org.apache.log4j.*" %>
<%@ page errorPage="/Error.jsp" %>

But this

<%@ page import="org.apache.log4j.*" %><%@ page 
errorPage="/Error.jsp" %>

Of course then your JSP is ugly and hard to read. Pick which one bugs you least or post-process the generated html, which I'm guessing is what the Tomcat switch enables.

Posted by Steve Raeburn on March 24, 2005 at 01:12 PM MST #

How about a tag that trims whitespace from it's content? This would probably be the best solution. Or you could use <c:set> which will do the same thing:
  <c:set var="dummy">
    <%@ page errorPage="/Error.jsp" %>
  </c:set>

Posted by Michael Slattery on March 25, 2005 at 07:12 AM MST #

Whoa - this is just what I need. I am generating cottage availability calendars in a complex JSTL page and it made 28,000 lines, mostly blank, for three 15 month calendars. With this flag it dropped to 231 lines. It would take a long time I imagine to transfer all those blanks to the user's browser. It is also hard to debug with all that whitespace. I tried it in Tomcat 5.0 and it didn't work even though the web.xml had a comment that it would. 5.5.7 works, now I must get my hosting company to upgrade my site from Tomcat 4 to 5.5.7. I was afraid I would gave to rewrite my JSTL heavy JSP page into a servlet or learn how to make filters work. Now I can get on with other things. Thanks for revealing this 'trick' to me. Charlie

Posted by Charles Havener on March 25, 2005 at 02:09 PM MST #

Its off by default since it would violate the servlet spec while turned on.

Posted by funkman on March 26, 2005 at 06:11 PM MST #

The simplest reason for the spaces is debugging. If spaces are removed then the runtime line numbers for what is left won't match the source line numbers.

Posted by Michael Musson on April 05, 2005 at 11:01 AM MDT #

A previous comment stated that the whitespace already exists in the document. This is not correct because if I use
<code> <c:set var=&quot;baseurl&quot; value=&quot;${pageContext.request.scheme}://${pageContext.request.serverName}&quot; /> </code>
And then later in my page use
<code> <param name=&quot;baseurl&quot; value=&quot;<c:out value=&quot;${baseurl}&quot; />&quot; /> </code>
The code is generated as
<code> <param name=&quot;baseurl&quot; value=&quot; http://myserver&quot; /> </code>

You can see that even though there is no whitespace before the c:out tag in the second fragment, but the final output has an empty space where the c:out tag begins.

Posted by SmK on June 26, 2005 at 12:50 PM MDT #

We have similar problem in our mobile site, thanks a lot for posting this solution. The problem was: we have forEach cycle in which we make DB query and depending on result we choose to display some data or not. In development to make code readable we used a lot of whitespace to make indentation. And thus a lot of whitespace was inside the cycle. As you probably guessed, it was added in every iteration, even if no useful data was inserted during this iteration. It made quite simple pages really big, but mostly filled with whitespace. Some mobile devices were unable to load some bigger pages - they were simply to big for the device, and it was a problem.

Posted by Noruas on March 14, 2006 at 06:26 AM MST #

re: yan cebron's comments: I don't think you need to escape the ampersand characters--this worked for me:
 <!-- Strip whitespace -->
    <replaceregexp match=">\s*<" replace="> <" flags="g" byline="false">
      <fileset dir="${build.home}" includes="**/*.html,**/*.htm,**/*.jsp,**/*.tag"/>
    </replaceregexp>
I'm using ant 1.6.1. The task above also just condenses between tags from many spaces to one space, rather than remove all of them (in case your tags output something that needs a space between them). I have found that you don't save as much doing the stripping at build time as you do at runtime.

Posted by Dan Moore on June 26, 2006 at 02:25 PM MDT #

Kris, You said "Oh, the jasper ant task has a flag to do the same thing if you pre-compile your JSPs..." what's the flag name/value?

Posted by Patrick O'Sullivan on August 23, 2006 at 06:20 AM MDT #

Brilliant! Absolutely brilliant! I'm spitting out some silly HTML on the order of 1.5MB to 2MB for a couple JSPs. I imagine at least 40% of that is whitespace that could be trimmed. Now... if I could just get it to work on Tomcat w/i JBoss. I'm editing this web.xml file: my_config/deploy/jbossweb-tomcat55.sar/conf/web.xml and adding the attribute but it doesn't seem to take. Anybody else get this to work on JBoss?

Posted by Jason Andersen on August 25, 2006 at 11:24 PM MDT #

for anyone who can't get trimSpaces = true to take... the problem is likely that the $CATALINA_BASE/work/Catalina/localhost directory contains already compliled taglibs and jsps that *aren't* deleted on simple restarts... rm -rf the relvant subsdirs there (eg, "_" for ROOT), and they're get repopulated correctly.

Posted by todd hodes on September 12, 2006 at 08:07 PM MDT #

Thank for that I have an init.jsp leaving a wide gap in every jsp. This hopefully will fix it Cheers

Posted by Viz on November 06, 2006 at 07:10 AM MST #

Any one has any solution for answering same in Weblogic server?

Posted by zzAA on May 23, 2007 at 01:42 AM MDT #

I have a problem here. When entering the details in the jsp page, when i give 2 words in a single text box seperated by spaces for ex like Key Board, the value gets stored exactly the same way in the Database after saving it. But in the webpage it only displays the first word 'Key'. The words after the space is not getting displayed. Even i have tried running the profiler and it executes without any problem. Even i have tried entering the values in the database manually and i am having the same exact problem. Can someone help me with this?

Posted by Nataraj on May 31, 2007 at 12:16 AM MDT #

Hey guys,

The solution provided below works great too!

1. Keep trimFlt.jar in WEB-INF\lib folder

Download this jar from the reference link provided at the end.

2. Add following entries in web.xml

 <filter> 
   <filter-name>trimFilter</filter-name> 
   <filter-class>com.cj.trim.trimFilter</filter-class> 
 </filter>
 
 <filter-mapping>
   <filter-name>trimFilter</filter-name> 
   <url-pattern>/*</url-pattern>
 </filter-mapping>

To remove other HTML comments the filter parameter can be changed to -

<filter> 
  <filter-name>trimFilter</filter-name> 
  <filter-class>com.cj.trim.trimFilter</filter-class> 
  <init-param> 
    <param-name>removeComments</param-name> 
    <param-value>true</param-value> 
  </init-param> 
</filter>

The performance impact of this fix is yet to be analysed.

Reference that I used - http://www.servletsuite.com/servlets/trimflt.htm

Posted by Ashish Nair on July 03, 2007 at 03:43 AM MDT #

zzAA -- the solution provided above works perfectly well for weblogic servers.

Posted by Ashish Nair on July 03, 2007 at 03:47 AM MDT #

Hi Matt, I am from Sri Lanka and these days am trying to configure appfuse (Localization to support sinhala language) . I used the sinhala unicode font and since utf-8 was used as the db encoding I was able to save the sinhala words in the db and was able to successfully retrieve it and display. Then I tried to put these unicode values in to ApplicationResources.properties file to enable the application to display local language labels and messages. Then I got few junk values displayed not the desired local language test. I have installed the unicode font correctly. When I removed the taglib declaration <%@ include file="/common/taglibs.jsp"%> from the JSP file (UserForm.jsp) I was able to view the local language text successfully. Can you please help me with this issue? is there a problem with taglib rendering and unicode fonts? pls help me on this issue. Thank you very much .....

Posted by Sanath Kodikara on July 11, 2007 at 12:41 AM MDT #

Sanath - please post any AppFuse related questions to the AppFuse Mailing List.

Posted by Matt Raible on July 11, 2007 at 12:45 AM MDT #

[Trackback] Since my last post on trimming whitespace in JSPs seems to be a popular topic, I figured it appropriate to note that JSP 2.1 supports a new trimWhitespace directive. To learn more about it, view Summary of New Features in JSP 2.1 Technology and sea...

Posted by Raible Designs on August 01, 2007 at 05:02 PM MDT #

Is there any such a feature [trim white spaces] for Websphere Application Server V6.1. If so, please let me know... I need it badly for WAS 6.1

Posted by Balakumar on October 25, 2007 at 04:11 AM MDT #

The trimFlt.jar mentioned above works great for standard HTML streams, but we're having problems getting it filter XHTML-MP for some reason. Is there any deeper documentation and/or any way to contact the developer? The servletsuite site is rather content-free, and I'd probably purchase the "commercial license" for $49, but only if I knew that buying it would give me more direct access to the developer and/or the code itself.

Any ideas?

Posted by Ken Scott on November 06, 2007 at 03:08 AM MST #

I have another issue, don't know whether its the right place to post it, if its not forgive me....I am using JSF and RichFaces , in the rich faces tree structure I am trying to display some text like "M O" but the browser is displaying "M O" same with normal HTML "<span >M O</span>" output is "M O" Is there any way we can tell the browser to display the space??? Any pointers in this regard would be very helpful. Regards Mim

Posted by Mim on December 03, 2007 at 11:17 PM MST #

use & n b s p; instead (i added spaces so it doesnt turn into a real space...) you comment didn't come out correct btw... =P needed to view the source to see what you were talking about

Posted by David Truong on January 30, 2008 at 12:52 PM MST #

Great resource Matt. I have been recommending this page to clients who are looking to remove whitespace for SEO purposes. I also included it in a J2EE optimization checklist that I put together. Thanks again!

Posted by jess on February 20, 2008 at 09:23 AM MST #

Awesome work here - just wondering if you can tell me along with the white space stripping, what command I can use as part of
<!-- Strip whitespace -->
    <replaceregexp match=">\s*<" replace="> <" flags="g" byline="false">
      <fileset dir="${build.home}" includes="**/*.html,**/*.htm,**/*.jsp,**/*.tag"/>
 </replaceregexp>
To remove line breaks and comments in JSP's?

Posted by Sam Allen on April 04, 2008 at 04:55 AM MDT #

But if you have <textarea> cccccc aaa cdd ddd </textarea> in html? I lost spaces and new line.....

Posted by leoj on May 12, 2008 at 03:22 AM MDT #

Post a Comment:
  • HTML Syntax: Allowed