In his blog, Bram Smeets has described mechanisms for configuring the DWR Ajax library with Spring (http://bram.jteam.nl/?p=2 - please read it before proceeding with this post).
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
<servlet-mapping> <servlet-name>main</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
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.SecurityException and 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
<prop key="/**/*.js">dwrController</prop> <prop key="exec/*">dwrController</prop>
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
/dwr prefix. So, for example
/dwr/engine.js will basically be treated as
engine.js and 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
productManager object defined in the Bram’s example will be converted to the
/dwr/exec/productManager.getAllProducts URL 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"/> <property name="mappings"> <props> <prop key="/dwr/**/*">dwrController</prop> </props> </property> </bean>
Have you experienced similar issues? How did you solve them?