Monthly Archives: July 2003

JavaScript hacking

Well… this isn’t quite java but should be interesting for the web developers out there.

When doing a bunch of img.src calls just before changing a div from invisible to visible, the images don’t get displayed properly (on some clients when the wind blows in the wrong direction).

This is after having to go to the pain of setting the img.src’s in the first place because of a bug on a different version of ie :(.

So before changing the div display attribute I have to do a sleep.

In a real language this would be a call to Thread.sleep or similar. JavaScript has a funky setTimeout method (this takes a string method to call so state can’t be passed in), but doesn’t support my usage because state is required.

Google led me to Guy’s World, who linked to a great article titled How do I pause execution in JavaScript?

The window.ShowModalDialog hack (I would use a different word but nothing but hack meets the requirements) discussed in the article is how I have got this working. Another ugly DHTML hack required to get things working in Microsoft land.

Clover coverage results

I have just started using clover on site. The Clover IntelliJ plug-in is cool, and makes for some great fun when working through and increasing test coverage.

Sometimes, however it can be hard to test the last couple of statements on a class.

I am really going to struggle to get the encoding exception on this bit of code tested….

try {
   stringBytes= string.trim().getBytes(“UTF-8″);
} catch (UnsupportedEncodingException e) {
   log.error(“This error is suprising — we really expect any jvm to support the UTF-8 encoding “+ e.getMessage(), e);
}

On Caching (with WebWork)

A while ago I implemented a dynamic caching solution for a client. I talked about this in Caching Dynamic Content. Since then I have run into some issues with the initial solution that I implemented, and I have now got a new and improved solution.

The primary problems with the earlier solution were:
1) New versions weren’t picked up (the coolness of the IE specific response settings weren’t cool enough — old data was being displayed too often).
2) Having the headers set directly in the JSP meant that the JSP content was generated each time that the date had to be checked (a 20 second piece of work).
3) The server was having to work too hard to generate content.

So a solution had to be found. Here’s what I ended up with.

Instead of going directly to the JSP (as in the initial solution) a WebWork action is the first point of contact. The action checks the request details, then sets some response headers (when the data hasn’t been updated) which allows generation of the JSP to be avoided altogether.

The action implements the Request and Response Aware interfaces giving access to the Response and Request (type 2 IoC).

Following are the details of what the action does:

First get the if-modified-since header:

long ifModifiedSince = request.getDateHeader(“If-Modified-Since”);

Then set some headers in the response to tell the client to always check the server for a new version of the page.

response.setHeader(“Cache-Control”, “must-revalidate”);
response.setDateHeader(“Expires”, 0);

The following sets the last-modified-date (the last modified date is used to derive the if-modified-since date in future requests)

response.setDateHeader(“Last-Modified”, lastModifiedTime);

Then the magic happens….
The action checks the ifModifiedTime against the ifModifiedSince time and sends a “not modified” error response code if the content hasn’t changed.

if (lastModifiedTime<= ifModifiedSince){
   response.sendError(HttpServletResponse.SCNOTMODIFIED);
   return null;
}

If the data has been modified then the system generates the new JSP, and returns the data to the client.

This means that the client does a round trip to the server each time that the content is requested. The server then does a cheap calculation and response for the 95% of cases where the data is current, and the other 5% of the time the new data is generated and returned. This is a solution that works well.

The reason it works so well is that each user has their own version of the data that they need to see. The content doesn’t change often, but when it does they need to see it straight away. If the data was less user specific another level of server side caching could be used with OSCache or a similar tool.