Archive for March, 2009
Encode URI
by Frank Kim on Mar.17, 2009, under Java SE
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;
}
Unobtrusive JavaScript
by Frank Kim on Mar.17, 2009, under 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.
mod_rewrite to bypass security
by Frank Kim on Mar.02, 2009, under HTTP Server, Struts
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"/>
Dynamically generate sitemap.xml
by Frank Kim on Mar.02, 2009, under Servlet
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>