Usar el dwr remótamente
Direct Web Remoting (dwr) es una librería que proporciona una API que permite realizar llamadas remotas a objetos Java del servidor desde código JavaScript cliente a través de Ajax.
La forma más comun es tener la parte del servidor y del cliente en la misma máquina, pero puede darse el caso en el que queramos tener la página cliente en otra máquina y acceder al drw remótamente. Esto no funciona por defecto y para que funcione, tendremos que hacer lo siguiente.
En la parte javascript tendremos que ejecutar estas dos órdenes antes de llamar a cualquier función de cualquier clase java publicada con el dwr (observar que la segunda orden tendremos que ejecutarla por cada clase java que utilicemos):
dwr.engine.setRpcType(dwr.engine.ScriptTag); MyClass._path = 'http://MYDOMAIN.COM/dwr';
Y en el fichero web.xml del servlet DwrServlet hay que poner a true los parámetros allowScriptTagRemoting y allowGetForSafariButMakeForgeryEasier:
<init-param> <param-name>allowScriptTagRemoting</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>allowGetForSafariButMakeForgeryEasier</param-name> <param-value>true</param-value> </init-param>
Un ejemplo sencillo de la parte cliente de una clase java de nombre MyClass con una función de nombre myFunction publicada en un dwr que esta en la url http://DOMAIN1.COM/dwr sería el siguiente:
<html> <head> <script type='text/javascript' src='http://MYDOMAIN1.COM/dwr/interface/MyClass.js'></script> <script type='text/javascript' src='http://MYDOMAIN1.COM/dwr/engine.js'></script> </head> <body> <script type="text/javascript"> dwr.engine.setRpcType(dwr.engine.ScriptTag); MyClass._path = 'http://MYDOMAIN1.COM/dwr'; MyClass.myFunction('parameter1',alert); </script> </body> </html>
Errores
Error 404 Not Found
Cuando se hace la llamada a una función de una clase java que esta publicada con el dwr (por ejemplo para una clase de nombre MyClass y una función myFunctión se llamaría a /dwr/call/plaincall/MyClass.myFunction.dwr), da un error http 404 Not Found.
Solución
El problema está en que cuando el dwr llama a la función de la clase, la llamada ajax la ejecuta como si el dwr estuviera en el mismo dominio que la aplicación cliente. Y como el dwr no esta en esa máquina, da ese error. Para que la llamada se haga con el dominio en el que esta el dwr (por ejemplo http://MYDOMAIN1.COM/dwr), tendremos que añadir en la aplicación cliente el siguiente código javascript antés de llamar a la función que queramos:
MyClass._path = 'http://MYDOMAIN.COM/dwr';
Error No data received from server
La petición ajax que se llama al ejecutar una función de una clase java publicada en el dwr, devuelve el estado http de exito 200. Pero no devuelve nada.
http://MYDOMAIN1.COM/dwr/call/plaincall/MyClass.myFunction.dwr No data received from server
Solución
El problema esta en que no hemos ejecutado el siguiente código javacript en la parte del cliente. Por lo que para solucionarlo tendremos que añadirlo a la parte cliente:
dwr.engine.setRpcType(dwr.engine.ScriptTag);
Error allowScriptTagRemoting is false
Cuando se hace la llamada a una función de una clase java que esta publicada con el dwr, nos aparece un error javascript que dice lo siguiente:
uncaught exception: allowScriptTagRemoting is false.
y en el log del servidor donde esta el dwr aparece la siguiente línea:
15:06:38,824 DEBUG DebuggingPrintWriter:43 - out(18): throw 'allowScriptTagRemoting is false.';
Solución
Tenemos que poner a true el parámetro allowScriptTagRemoting del servlet DwrServlet. Para ello tendremos que editar el fichero web.xml y añadir el siguiente parámetro para ese servlet:
<init-param> <param-name>allowScriptTagRemoting</param-name> <param-value>true</param-value> </init-param>
Error Get is disallowed
Al llamar a una función de una clase java publicada en el dwr, nos da el siguiente error javascript:
engine.js (línea 1310) Error: java.lang.SecurityException, GET Disalowed
y en el log del servlet aparece el siguiente error:
15:16:34,238 ERROR Batch:75 - GET is disallowed because it makes request forgery easier. See http://getahead.org/dwr/security/allowGetForSafariButMakeForgeryEasier for more details.
Solución
Tenemos que poner a true el parámetro allowGetForSafariButMakeForgeryEasier del servlet DwrServlet. Para ello tendremos que editar el fichero web.xml y añadir el siguiente parámetro para el servlet indicado:
<init-param> <param-name>allowGetForSafariButMakeForgeryEasier</param-name> <param-value>true</param-value> </init-param>