Download Desarrollo de un EJB para la georreferenciación utilizando
Document related concepts
no text concepts found
Transcript
Desarrollo de un EJB para la georreferenciación utilizando webservices y el servicio de GeoNames Versión 0.1 Jorge Iván Meza Martínez http://www.jorgeivanmeza.com/ <[email protected]> 2008 Introducción El presente documento describe el desarrollo de una aplicación para la georreferenciación de ubicaciones a partir del su nombre utilizando el servicio web de GeoNames. Esta aplicación se desarrolla utilizando el IDE Netbeans y el servidor de aplicaciones GlassFish. La arquitectura de la solución corresponde con la mostrada a continuación. El GeoLocalizationBean consume el servicio de GeoNames para resolver la latitud y longitud (entre otra información) de cualquier ubicación en el mundo, descrita por por una cadena de texto referenciando su nombre. El EJB implementa el método geoCode el cual a partir de la cadena con la ubicación y el servicio de geolocalización obtiene la información georreferenciada y la retorna como arreglo (múltiples respuestas) de un Hashtable (parejas de información llave => valor). El EJB es expuesto al exterior a través del servicio web GeoLocalizationService el cual presenta el método geoCode el cual a partir de la descripción de la ubicación utiliza el EJB para calcular su información georreferenciada y retornarla como una cadena de texto que representa la información a través de XML. El cliente de escritorio utilizado para la demostración de este servicio, GeoLocalizationClient, consume el servicio web descrito en el párrafo anterior enviandole la información de la ubicación solicitada y recibiendo de él la representación en XML del resultado el cual muestra en el contexto de su ventana este documento recién recibido. El órden de desarrollo es entonces el mismo de la descripción: EJB → WS → Cliente. Implementación del EJB (lógica del negocio). El objetivo de esta capa de la aplicación es la de recibir la solicitud del usuario junto con la información de la ubicación que se desea georreferenciar y contactar con ella directamente al servicio de un tercero para obtener esta información. El bean después de recibir la solicitud hace el requerimiento externo y al recibir su respuesta se la transmite directamente al solicitante, terminando con esto cualquier tipo de relación o proceso y sin la necesidad de requerir un conocimiento futuro del cliente, por esto se desarrollo utilizando un EJB de sesión sin estado (stateless). Utilizando la herramienta de desarrollo se crea entonces el proyecto (Proyecto2) de tipo Enterprise > EJB Module. Para la utilización del API provisto por GeoNames es necesario que se agregue al CLASSPATH los archivos: geonames-1.0.jar y jdom-1.0.jar (ver GeoNames source code), esto se hace añadiendo JAR/Folder en la rama de Librerías del proyecto. A continuación se crea el EJB GeoLocalizationBean agregando un nuevo Session Bean al proyecto. El bean será ubicado en el paquete uam.gis, su tipo de sesión será sin estado (Stateless) por las razones descritas en la sección anterior y se le creará su interfaz remota únicamente. Al recién creado GeoLocalizationBean se le crea un método del negocio a través de Add > Business Method. Este método deberá pertenecer a la interfaz remota, llamarse geoCode, recibir una cadena (location) como parámetro y retornar un arreglo de tipo Hashtable con el resultado. Editamos ahora el código fuente del método (Go To Source) el cual se describe parcialmente a continuación (ver Proyecto2\src\java\uam\gis\GeoLocalizationBean.java para mayor información). // Se prepara el objeto que encapsula los criterios de la búsqueda ToponymSearchCriteria searchCriteria = new ToponymSearchCriteria(); searchCriteria.setQ(location); // Se realiza la solicitud de búsqueda de la localización ToponymSearchResult searchResult = org.geonames.WebService.search(searchCriteria); // Se reciben los resultados (topónimos) obtenidos. Téngase en cuenta que la búsqueda // puede arrojar resultados múltiples según el criterio elegido List<Toponym> toponyms = searchResult.getToponyms(); // Se construye un Hashtable basado en la información recién recibida Hashtable[] results = new Hashtable[toponyms.size()]; int index = 0; for (Toponym toponym : toponyms) { results[index] = new Hashtable(); results[index].put("CountryCode", toponym.getCountryCode()); results[index].put("CountryName", toponym.getCountryName()); results[index].put("GeoNameId", toponym.getGeoNameId()); results[index].put("Latitude", toponym.getLatitude()); results[index].put("Longitude", toponym.getLongitude()); results[index].put("Name", toponym.getName()); results[index].put("Style", toponym.getStyle().toString()); results[index].put("Elevation", toponym.getElevation()); results[index].put("Population", toponym.getPopulation()); results[index].put("TimeZone", toponym.getTimezone().toString()); index ++; } // Se retorna el resultado construído return results; Se reconstruye el proyecto (Clean and Build) lo cual debe realizarse sin problemas y es entonces cuando se despliega nuevamente (Undeploy and Deploy) para su publicación en el servidor de aplicaciones. Implementación del servicio web (publicación del servicio). El objetivo de esta capa es el de permitir a los clientes (remotos) acceder al servicio de georreferenciación que provee el EJB implementado en el paso anteiror. Para implementar el servicio web se crea un proyecto de tipo Web > Web Application. Su nombre será Proyecto2_WebService. El primer paso es agregar la referencia al EJB que se va a acceder a través del servidor de aplicaciones, para esto se agrega el proyecto (Add Project) en la sección de librerías (Libraries) y se selecciona el EJB (Proyecto2/Proyecto2.jar). Como el método a invocarse es suceptible de lanzar una excepción no estándar (basada en los paquetes de un tercero: org.geonames.InsufficientStyleException) se agrega el JAR/Folder de la librería (geonames-1.0.jar) al proyecto. El siguiente paso es crear el método que se expondrá efectivamente a través del servicio web. Para esto se crea un New > Web Service llamado GeoLocalizationService, se ubica en el paquete uam.gis, se crea basado en un bean de sesión previo (Create web service from existing session bean) y se selecciona el EJB implementado en la sección anterior: Proyecto2 > Enterprise Beans > GeoLocalizationBean. Se agrega una operación llamada geoCode que recibe un parámetro tipo cadena llamado location y retorna un String que contendrá la representación en XML del resultado. La implementación del método se describe a parcialmente continuación (ver Proyecto2_Webservice\src\java\uam\gis\GeoLocalizationService.java para mayor información). // Se empieza a preparar la cadena que contendrá el // resultado de la georreferenciación String xml = "<localizations>\n"; // Se realiza la consulta remota al EJB Hashtable[] response = ejbRef.geoCode(location); // Recorre cada uno de los elementos para procesarlos // y construír con su información registros XML for(int i=0; i<response.length; i++) { // Obtiene la información del registro actualmente procesado Hashtable v = response[i]; // Agrega la sección lugar (place) xml += "<place>\n"; // Recorre cada una de las llaves disponibles en el Hashtable for(Object key : v.keySet()) { // Obtiene el valor correspondiente con la llave actual String value = (String) v.get(key).toString(); // Crea un valor XML con el nombre de la llave y // su correspondiente valor xml += "<" + key.toString().toLowerCase() + ">" + value + "</" + key.toString().toLowerCase() + ">\n"; } // Cierra la sección lugar (place) xml += "</place>\n"; } // Cierra la sección de localizaciones (localizations) xml += "</localizations>\n"; // Retorna al cliente solicitante la información XML // recién preparada return xml; Se reconstruye el proyecto (Clean and Build) lo cual debe realizarse sin problemas y es entonces cuando se despliega nuevamente (Undeploy and Deploy) para su respectiva publicación. Implementación del cliente de escritorio (consumir el servicio). La misión de este módulo es la de permitir al usuario final georreferenciar información (cliente), es decir, consumir el servicio web creado en la sección anterior que a su vez accede al EJB creado en la primera sección. Para realizar su implementación se creó un proyecto de tipo Java > Java Desktop Application cuyo nombre es Proyecto2_GeoLocalization_Client. El primer paso es agregar la referencia al servicio web creado en la sección anterior. Para hacer esto se selecciona New > Web Service Client a partir del proyecto. Se elije el proyecto (Project) como orígen del WSDL y se selecciona Proyecto2_WebService > GeoLocalizationService. El paso siguiente es definir la interfaz gráfica de usuario (GUI) que tendrá la ventana del cliente (Proyecto2_GeoLocalization_ClientView.java). Al respecto se preparan los siguientes componentes. La aplicación deberá permitir entonces que el usuario escriba en el campo de texto (jTextField1) la información a georreferenciar, presione el botón Geocodificar y se despliegue el resultado en el campo de texto (jEditorPane1). Para esto se presenta a continuación el código parcial del método que deberá atender el evento de presionar el botón de geocodificar (ver Proyecto2_GeoLocalization_Client\src\proyecto2_geolocalization_client\Proyecto2_GeoLocalization _ClientView.java para mayor información). // Se prepara la conexión con el servicio web GeoLocalizationService uam.gis.GeoLocalizationServiceService service = new uam.gis.GeoLocalizationServiceService(); uam.gis.GeoLocalizationService port = service.getGeoLocalizationServicePort(); // Se obtiene la ubicación a geolocalizar enviada por el usuario String location = this.jTextField1.getText(); // Se realiza la consulta remota al servicio web String result = port.geoCode(location); // Se despliega la respuesta obtenida (XML) en la interfaz del usuario jEditorPane1.setText(result); Referencias de información. Netbeans http://www.netbeans.org/ GlassFish http://www.glassfish.org/ UMLet http://www.umlet.com/ GeoNames http://www.geonames.org/ End-to-End Web Service Tutorial: Flower Application http://www.netbeans.org/kb/60/websvc/ejb.html