4. Uso de la aplicación
Ahora queremos ejecutar la aplicación fuera de IDE y STS (para el servidor) y Webstorm (para el cliente).
4.1. Implementación del servicio web en un servidor Tomcat
En el apartado 2.11.9 vimos cómo crear un archivo WAR para Tomcat. Repetimos aquí la operación. En primer lugar, para conservar lo existente, duplicamos el proyecto Eclipse [rdvmedecins-webapi-v3] en [rdvmedecins-webapi-v4].
![]() |
El archivo [pom.xml] se modifica de la siguiente manera:
<modelVersion>4.0.0</modelVersion>
<groupId>istia.st.spring4.mvc</groupId>
<artifactId>rdvmedecins-webapi-v4</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>rdvmedecins-webapi-v3</name>
<description>Gestion de RV Médecins</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>istia.st.spring4.rdvmedecins</groupId>
<artifactId>rdvmedecins-metier-dao-v2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
Los cambios deben realizarse en dos lugares:
- línea 5: hay que indicar que se va a generar un archivo WAR (Web ARchive);
- líneas 23-27: hay que añadir una dependencia del artefacto [spring-boot-starter-tomcat]. Este artefacto incluye todas las clases de Tomcat en las dependencias del proyecto;
- línea 26: este artefacto es [provided], es decir, que los archivos correspondientes no se incluirán en el WAR generado. De hecho, estos archivos se encontrarán en el servidor Tomcat en el que se ejecutará la aplicación;
Además, hay que configurar la aplicación web. A falta del archivo [web.xml], esto se hace con una clase que hereda de [SpringBootServletInitializer]:
![]() |
La clase [ApplicationInitializer] es la siguiente:
package rdvmedecins.web.config;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class ApplicationInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
}
- línea 6: la clase [ApplicationInitializer] extiende la clase [SpringBootServletInitializer];
- línea 8: el método [configure] se redefine (línea 7);
- línea 9: se proporciona la clase [AppConfig] que configura el proyecto;
Una vez hecho esto, puede ser necesario actualizar el proyecto Maven (yo tuve que hacerlo): [clic droit sur projet / Maven / Update project] o [Alt-F5].
Para ejecutar el proyecto, se puede proceder de la siguiente manera:
![]() |
- en [1], se ejecuta el proyecto en uno de los servidores registrados en IDE Eclipse;
- en [2], se selecciona [tc Server Developer], que está presente por defecto. Se trata de una variante de Tomcat;
Se obtiene el siguiente resultado:
![]() |
Es normal. Recordemos que el servicio web no tiene URL ni [/] entre sus métodos. Al probar URL y [/getAllMedecins], se obtiene la siguiente respuesta:
![]() |
Es normal. El servicio web está protegido.
Ahora ejecutemos el cliente [rdvmedecins-angular-v2] en Webstorm:
![]() |
En [1], introducimos el URL del nuevo servicio web [http://localhost:8080/rdvmedecins-webapi-v4]. Obtenemos el siguiente resultado:

Para ejecutar la aplicación fuera del IDE STS, existen varias soluciones. Aquí tienes una.
Descargue un version de Tomcat [http://tomcat.apache.org/download-80.cgi] (julio de 2014):
![]() |
En [1], seleccionamos un archivo version comprimido y lo descomprimimos en [2]. Volvemos a STS:
![]() |
- en la pestaña [Servers], hacemos clic con el botón derecho del ratón en la aplicación [rdvmedecins-webapi-v4] y seleccionamos option [Browse Deployment Location];
- en [4]: se copia la carpeta [rdvmedecins-webapi-v4];
![]() |
- en [5], pegamos la carpeta [rdvmedecins-webapi-v4] en la carpeta [webapps] de Tomcat;
- en [6], se ejecuta el archivo de comando [startup.bat] (el servidor Tomcat integrado en STS debe estar detenido). Se abre una ventana DOS para mostrar los registros de Tomcat. Estos deben indicar que se ha iniciado la aplicación [rdvmedecins-webapi-v4].
Para verificarlo, se vuelve a ejecutar el cliente Angular [rdvmedecins-angular-v2] en Webstorm:
![]() |
En [1], se introduce el URL del nuevo servicio web [http://localhost:8080/rdvmedecins-webapi-v4]. Se obtiene el siguiente resultado:

4.2. Implementación del cliente Angular en el servidor Tomcat
Ahora que el servicio web se ha implementado en Tomcat, vamos a implementar también el cliente Angular en un servidor. Este puede ser perfectamente el servidor que ya aloja el servicio web. Optamos por esta vía.
En primer lugar, duplicamos el cliente [rdvmedecins-angular-v2] en [rdvmedecins-angular-v3] y realizamos las siguientes modificaciones:
![]() |
- en [1], todo se ha trasladado a una carpeta [app] ;
- en [1], se ha eliminado la carpeta [bower-components] que contenía las diversas bibliotecas CSS y JS necesarias para el proyecto. Todos estos elementos se han copiado en la carpeta [lib] [2];
- en [1], el archivo [app.html] se renombró como [index.html];
El archivo [index.html] se ha modificado para tener en cuenta los cambios en las rutas de los recursos utilizados:
<!DOCTYPE html>
<html ng-app="rdvmedecins">
<head>
<title>RdvMedecins</title>
...
<!-- el CSS -->
...
<link href="lib/bootstrap-theme.min.css" rel="stylesheet"/>
<link href="lib/bootstrap-select.min.css" rel="stylesheet"/>
</head>
<!-- controlador [appCtrl], plantilla [app] -->
<body ng-controller="appCtrl">
<div class="container">
...
</div>
<!-- Bootstrap core JavaScript ================================================== -->
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/bootstrap-select.min.js"></script>
<script type="text/javascript" src="lib/footable.js"></script>
<!-- angular js -->
<script type="text/javascript" src="lib/angular.min.js"></script>
<script type="text/javascript" src="lib/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="lib/angular-route.min.js"></script>
<script type="text/javascript" src="lib/angular-translate.min.js"></script>
<script type="text/javascript" src="lib/angular-base64.min.js"></script>
<!-- módulos -->
...
<!-- servicios -->
...
<!-- directivas -->
...
<!-- controladores -->
....
</body>
</html>
Además, se ha modificado el controlador [loginCtrl] para que apunte al servidor correcto y así evitar que el usuario tenga que escribir su URL:
// credenciales
app.serverUrl = "http://localhost:8080/rdvmedecins-webapi-v4";
app.username = "admin";
app.password = "admin";
Una vez hecho esto, ejecutemos el archivo [index.html]:
![]() | ![]() |
A continuación, conectémonos al servicio web. Debería funcionar. Una vez comprobado esto, detengamos el servidor Tomcat. Vamos a reutilizar el servidor integrado de STS.
En STS, copiamos todo el contenido de la carpeta [rdvmedecins-angular-v3/app] a la carpeta [webapp] del proyecto [rdvmedecins-webapi-v4] (pestaña Navigator) [1]:
![]() |
Una vez hecho esto, iniciemos [2], el servidor VMware de STS, y luego solicitemos el URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]:
![]() |
Tenemos un problema de permisos en [3]. No es de extrañar, ya que hemos protegido el servicio web. Debemos declarar que el acceso al archivo [/app/index.html] es libre. Volvamos a Eclipse:
![]() |
Recordemos que los derechos de acceso se han declarado en la clase [SecurityConfig]. Modifiquemos esta clase de la siguiente manera:
@Override
protected void configure(HttpSecurity http) throws Exception {
// CSRF
http.csrf().disable();
// la contraseña se transmite mediante el encabezado Authorization: Basic xxxx
http.httpBasic();
// el método HTTP OPTIONS debe estar autorizado para todos
http.authorizeRequests() //
.antMatchers(HttpMethod.OPTIONS, "/", "/**").permitAll();
// la carpeta [app] es accesible para todos
http.authorizeRequests() //
.antMatchers(HttpMethod.GET, "/app", "/app/**").permitAll();
// solo el rol ADMIN puede utilizar la aplicación
http.authorizeRequests() //
.antMatchers("/", "/**") // todos los URL
.hasRole("ADMIN");
}
- líneas 11-12: permitimos que todo el mundo lea la carpeta [app] y su contenido. Para ello, nos basamos en las líneas anteriores.
Ahora, reiniciemos el servidor Tomcat de STS y volvamos a solicitar URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]:

Esta vez sí funciona.
4.3. Los encabezados CORS
Quizás recordemos que nos costó mucho trabajo gestionar los encabezados CORS. En el ejemplo anterior:
- el servicio web está en URL [http://localhost:8080/rdvmedecins-webapi-v4];
- el cliente HTML está en URL [http://localhost:8080/rdvmedecins-webapi-v4/app];
Por lo tanto, el cliente HTML y el servicio web se encuentran en el mismo servidor [http://localhost:8080]. Así pues, no hay conflictos CORS, ya que estos solo se producen cuando el cliente y el servidor no están en el mismo dominio. Deberíamos poder verificarlo. Volvemos a STS:
![]() |
La generación o no de los encabezados CORS se controla mediante un valor booleano definido en la clase [ApplicationModel]:
// datos de configuración
private boolean CORSneeded = true;
Ponemos el valor booleano anterior en false, reiniciamos el servicio web y volvemos a solicitar el URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html]. Se observa que la aplicación funciona.
4.4. Implementación del cliente Angular en una tableta Android
La herramienta [Phonegap] [http://phonegap.com/] permite generar un ejecutable para dispositivos móviles (Android, IoS, Windows 8, ...) a partir de una aplicación HTML / JS / CSS. Hay diferentes formas de lograrlo. Nosotros utilizamos la más sencilla: una herramienta disponible en línea en el sitio web de Phonegap [http://build.phonegap.com/apps].
![]() |
- antes de [1], es posible que tengas que crear una cuenta;
- en [1], empezamos;
- en [2], se elige un plan gratuito que solo permite una aplicación Phonegap;
![]() |
- en [3], descargamos la aplicación comprimida [4] (la carpeta [app] creada en el apartado 4.2 está comprimida);
![]() |
- en [5], se le da un nombre a la aplicación;
- en [6], se compila. Esta operación puede tardar 1 minuto. Espere hasta que los iconos de las diferentes plataformas móviles indiquen que la compilación ha finalizado;
![]() |
- solo se han generado los binarios de Android [7] y Windows [8];
- haga clic en [7] para descargar el binario de Android;
![]() |
- en [9], el binario [apk] descargado;
Inicie un emulador [GenyMotion] para una tableta Android (véase el apartado 6.4):
![]() |
Arriba, se inicia un emulador de tableta con el API 16 de Android. Una vez iniciado el emulador,
- desbloquéelo deslizando el pestillo (si lo hay) hacia un lado y soltándolo;
- con el ratón, arrastre el archivo [PGBuildApp-debug.apk] que ha descargado y suéltelo en el emulador. Se instalará y ejecutará;
![]() |
Hay que cambiar URL por [1]. Para ello, en una ventana de comandos, escribe el comando [ipconfig] (línea 1 a continuación), que mostrará las diferentes direcciones IP de tu equipo:
C:\Users\Serge Tahé>ipconfig
Configuration IP de Windows
Carte réseau sans fil Connexion au réseau local* 15 :
Statut du média. . . . . . . . . . . . : Média déconnecté
Suffixe DNS propre à la connexion. . . :
Carte Ethernet Connexion au réseau local :
Suffixe DNS propre à la connexion. . . : ad.univ-angers.fr
Adresse IPv6 de liaison locale. . . . .: fe80::698b:455a:925:6b13%4
Adresse IPv4. . . . . . . . . . . . . .: 172.19.81.34
Masque de sous-réseau. . . . . . . . . : 255.255.0.0
Passerelle par défaut. . . . . . . . . : 172.19.0.254
Carte réseau sans fil Wi-Fi :
Statut du média. . . . . . . . . . . . : Média déconnecté
Suffixe DNS propre à la connexion. . . :
...
Anote bien la dirección IP de la red Wi-Fi (líneas 6-9), bien la dirección IP de la red local (líneas 11-17). A continuación, utilice esta dirección IP en el URL del servidor web:
![]() |
Una vez hecho esto, conéctese al servicio web:
![]() |
Pruebe la aplicación en el emulador. Debería funcionar. En el lado del servidor, se pueden autorizar o no los encabezados CORS en la clase [ApplicationModel]:
// datos de configuración
private boolean CORSneeded = false;
Esto no tiene importancia para la aplicación de Android. Esta no se ejecuta en un navegador. Sin embargo, el requisito de los encabezados CORS proviene del navegador y no del servidor.
4.5. Implementación del cliente Angular en el emulador de un smartphone Android
Repetimos la operación anterior con un emulador de smartphone. Queremos comprobar cómo se comporta nuestro cliente en pantallas pequeñas:
![]() |
- en [1], iniciamos un emulador de smartphone;
- en [2] y [3], la barra de navigation se ha plegado en un menú;
![]() |
- en [4], se inicia sesión;
- en [5], la lista y el calendario están uno debajo del otro en lugar de estar uno al lado del otro;
![]() |
- en [6], se solicita el agenda;
- en [7], como la pantalla es demasiado pequeña, parte de los intervalos queda oculta. La biblioteca [footable] se ha encargado de esta tarea;
![]() |
- en [8], la misma vista que antes, pero esta vez con una cita.
En definitiva, nuestra aplicación se adapta bastante bien al smartphone. Seguramente podría ser mejor, pero sigue siendo usable.





























