Spring and DWR revisited
by Dejan Bosanac
That document contains the complete guide that you will need to get started with Ajax in your Spring-enabled Java projects and it is a de-facto tutorial for that topic.
However, there is one issue that bother me with the solution described in that blog. In order to describe this issue, let me first explain how this DWR-Spring integration works.
First of all, you have to put the following configuration snippet in your
This configuration maps all URLs that are under
/dwr/path to your Spring's
Now we need to map DWR calls to the appropriate DWR controller bean in the instance of our Spring's
In this example it is done by adding the following property
to the end of the class's 'mappings'.
In this configuration all requests that are not matched against any other previous pattern are sent to the DWR controller. The appropriate DWR calls are handled correctly and everything looks just fine.
The problem emerges for requests that are not DWR calls, but are matched against this pattern and sent to the DWR controller. As you can guess those are requests for which we expect 404 (page not found) status to be returned. Unfortunately, these requests are passed to the DWR controller that will throw
java.lang.SecurityExceptionand thus return a response with 505 (Error) status.
This can be a problem for your web application, especially if you want to receive an email for every exception that is thrown. In this case the DWR controller will generate a bulk of emails for every 404 response (usually generated by various spiders if you run a public web site).
One simple solution is to replace the previous mapping configuration with the following one
Let me explain how this configuration is different and what benefits does it bring.
When you encounter this problem, your first try would probably be to map all URLs that matches
/dwr/**/*pattern to the DWR Controller. Unfortunately, this won't work, because Spring (in a default configuration) sees these URLs without the
/dwrprefix. So, for example
/dwr/engine.jswill basically be treated as
engine.jsand obviously we have to find another solution.
engine.js, which is usually located at
Secondly, every call to a method defined in the interface is mapped to a certain URL. For example, a call to the
getAllProducts()method of the
productManagerobject defined in the Bram's example will be converted to the
/dwr/exec/productManager.getAllProductsURL request. All these URLs starts with
/dwr/exec/so we must match them against
exec/pattern. So with the second configuration line, we map this kind of URLs to our DWR controller.
With this solution we have allowed normal functioning of our DWR controller and assured that it will handle only requests that are regular Ajax calls. Also, it will improve the performance of your application a little bit, since there will be no 'false' Ajax calls for every 404 response.
Update: Bram have suggested a more cleaner solution to this issue (look at the comments for more details about this discussion). The trick is to define a new url mapper that will handle just DWR URLs. The final solution could look like this:
<bean id="dwrUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="alwaysUseFullPath" value="true"/>
Have you experienced similar issues? How did you solve them?
You have a good point here.
It has been a while back when I wrote my blog entry and it is due to a major update, covering this and some other issues.
Bram, you are absolutely right, the solution with
However, in my case I was dealing with live project with a lot of mappings (and no full paths enabled) so I didn't want to experiment with that funcionallity. My next Spring-DWR project will definitelly start with full paths :)
Even on an existing project, it poses no problem to add an extra mapping definition, which has the
It seem that I have been just too lazy to come up with the second URL mapper :) This is great. I have updated the post with this configuration, so that others could find it without reading the comments. Thanks.