Encode URI

To encode an URI you can simply use Java’s URLEncoder’s encode method which has been available since JDK 1.4.

String encodedUri;
  try {
    encodedUri = URLEncoder.encode(uri, "UTF-8");
  }
  catch (UnsupportedEncodingException exc) {
    // this should never happen
    logger.warn("UTF-8 is not a supported encoding?  Not encoding for now...", exc);
    encodedUri = uri;
  }
Share

Unobtrusive JavaScript

Unobtrusive JavaScript’s goal is to move all the functionality (the Controller) out of the HTML (the Model) and the CSS (the View).  This is also called full MVC separation.

This is how typically JavaScript and HTML mix.  For example in submitting a form using a text link.

<a href="javascript:submit(document.testForm)">Submit</a>

Or for jumping to different parts of a page using a dropdown.

 <input type="image" src="/img/buttons/update.gif"
   onClick="window.location.hash=
document.jumpTo.names.options[document.jumpTo.names.selectedIndex].value">

Using the unobtrusive JavaScript technique one can separate the JavaScript from the HTML.

<div id="foo">Submit</div>

<script type="text/javascript">
 Event.observe($('foo'), 'click', function(event) {
   $(Event.element(event)).form.submit();
   return false;
 });
</script>

We use the Protoculous JavaScript file which combines the Prototype framework and Scriptaculous libraries to do unobtrusive JavaScript.

Share

mod_rewrite to bypass security

Many Apache webserver installations use uriworkermap to configure requests are forwarded to Tomcat/JBoss and which are not.   This provides a certain level of security.  For example:

## APACHE RESOURCES (static files):
!/*.gif=myapp
!/*.html=myapp

## DISALLOW  (security-related filter):
!/*.jsp=myapp
!/*.xml=myapp

## TOMCAT RESOURCES:
/*.do=myapp

However if you dynamically generate your sitemap.xml or any other XML files using a servlet then this security will be a problem since the XML request will not make it to Tomcat/JBoss.  This is when mod_rewrite comes to the rescue.

You can set up mod_rewrite to rewrite the sitemap.xml request to be a sitemap.do request.

RewriteRule ^/sitemap\.xml$ /sitemap.do [PT,L]

Then you can set up Struts to forward this request to sitemap.xml.

<action path="/sitemap" forward="/sitemap.xml"/>
Share

Dynamically generate sitemap.xml

sitemap.xml is a top level document on your website “for webmasters to inform search engines about pages on their sites that are available for crawling.”  Google not surprisingly has its own documentation on how to improve your site’s visibility using sitemap.xml.

Typically sitemap.xml is a static file that is hand generated.  But on large sites it makes more sense to generate this dynamically.  One way to do this is to generate it on demand using a servlet.  Here is my simple solution.  I did not include the implementation for outputPages() since that will be specific to each application server’s DB hierarchy or web server’s file structure.

public class SiteMap extends HttpServlet {

  protected static final String MIME_TYPE_XML = "application/xml";

  // XML tags
  protected static final String SITE_MAP_XML_INFO = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  protected static final String SITE_MAP_BEGIN =
      "<urlset\n\txmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n\t\thttp://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">";
  protected static final String SITE_MAP_END = "</urlset>";

  protected static final String LOC_BEGIN = " <loc>";
  protected static final String LOC_END = "</loc>";
  protected static final String PRIORITY_BEGIN = " <priority>";
  protected static final String PRIORITY_END = "</priority>";
  protected static final String URL_BEGIN = "<url>";
  protected static final String URL_END = "</url>";

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

    // set content type to be XML
    response.setContentType(MIME_TYPE_XML);

    // get writer
    PrintWriter out = response.getWriter();

    // output header
    out.println(SITE_MAP_XML_INFO);
    out.println(SITE_MAP_BEGIN);

    // output pages
    outputPages(request, out);

    // output end
    out.println(SITE_MAP_END);
    out.close();
  }

  protected void outputPage(String uri, String priority, PrintWriter out, String urlStart) {
    out.println(URL_BEGIN);
    out.println(LOC_BEGIN + urlStart + uri + LOC_END);
    out.println(PRIORITY_BEGIN + priority + PRIORITY_END);
    out.println(URL_END);
  }
}

Then you configure web.xml to use the SiteMap servlet.

<servlet>
    <servlet-name>sitemap</servlet-name>
    <servlet-class>com.upromise.olm.app.servlet.SiteMap</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>sitemap</servlet-name>
    <url-pattern>/sitemap.xml</url-pattern>
</servlet-mapping>
Share