1. Configuración de Eclipse
El proyecto HybridServer que se ofrece como base del desarrollo está configurado para utilizar la codificación de caracteres UTF-8 y el salto de línea propio de Unix en el código fuente. Por lo tanto, antes de empezar a programar se debe comprobar que estos parámetros son correctos tras la importación.
Para ello, con el proyecto abierto y seleccionado en Eclipse, debe irse a Project->Properties
. Una vez se abra el diálogo de propiedades, debe irse al panel Resource, donde hay que comprobar que están seleccionados los siguientes valores:
- Text file encoding: UTF-8
- New text file line delimiter: Unix
2. Creación de un UUID
Java incluye la clase java.util.UUID
que permite generar identificadores únicos de una forma sencilla. Para ello, primero hay que generar un UUID aleatorio y, a continuación, convertirlo en una cadena de texto. Por ejemplo:
UUID randomUuid = UUID.randomUUID();
String uuid = randomUuid.toString();
Con esto tendremos en la variable uuid
un identificador único aleatorio similar a 550e8400-e29b-41d4-a716-446655440000
.
3. Simplificación del Protocolo HTTP
No es necesario que el servidor implemente el protocolo HTTP, tan solo será necesario cumplir con un pequeño conjunto de sus funcionalidades.
Algunas de las simplificaciones más importantes que aplicaremos son que:
- Siempre utilizaremos la codificación de caracteres UTF-8.
- No es necesario dar soporte al esquema de conexión "keep-alive". Las conexiones siempre se cierran tras manejar una única petición (p.ej. servir una página, eliminar una página, etc.).
- Salvo algunas cabeceras importantes, como
Content-Type
yContent-Length
, no es necesario tenerlas en cuenta. - No es necesario dar soporte a cookies.
4. Contenido URL-Encoded
Es habitual que los navegadores envíen el contenido de los formularios condificados en formato URL (URL encoded). Cuando esto ocurre, la petición HTTP contendrá la cabecera Content-Type: application/x-www-form-urlencoded
.
En dichos casos, el contenido deberá ser decodificado. Para ello se puede utilizar la clase java.net.URLDecoder
de la siguiente forma:
java.net.URLDecoder.decode(contenido, "UTF-8")
De este modo, después de guardar el contenido de una petición HTTP (clase HTTPRequest
), deberemos hacer algo de este estilo para que se almacene de forma correcta:
String type = headerParams.get("Content-Type");
if (type != null && type.startsWith("application/x-www-form-urlencoded")) {
content = URLDecoder.decode(content, "UTF-8");
}
HTTPRequest.toString()
5. Problemas con En el caso de que los tests que utilicen el método HTTPRequest.toString()
fallen, es muy probable que se deba al orden de las cabeceras o de los parámetros del contenido. En tal caso, la solución más sencilla es almacenar estos parámetros en un LinkedHashMap
, que mantiene el orden de inserción.
6. Peticiones HTTP
Una forma sencilla de probar el servidor es utilizar una herramienta del estilo de Restlet Client, que facilita el hacer peticiones HTTP a una URL concreta.
7. Base de datos
En los tests, la base de datos utilizada por defecto se llama hstestdb
y se accede con el usuario hsdb
con password hsdbpass
.
La base de datos utilizada debe contener una única tabla que se llame HTML
(deben respetarse las mayúsculas y minúsculas) con los campos:
-
uuid
de tipoCHAR(36)
. Será la clave primaria. -
content
de tipoTEXT
en MySQL oLONG VARCHAR
en JavaDB.
La base de datos estará creada, por lo que el servidor no debe contener ninguna sentencia ni función de creación de la base de datos.
8. Properties
La clase Properties
de Java es similar a un Map
, ya que contiene parejas de clave-valor. En el caso de Properties
, el acceso a los valores se hace con getProperty(String key):String
y el almacenamiento de valores se hace con setProperty(String key, String value)
.
Además, la clase Properties
permite recuperar fácilmente las propiedades de un fichero mediante los métodos load
. Estos métodos esperan que las propiedades estén almacenadas en el fichero de la siguiente manera:
prop1=value1
prop2=value2
prop3=value3
Las propiedades que se utilizarán y sus valores por defecto son los siguientes:
numClients=50
port=8888
db.url=jdbc:mysql://localhost:3306/hstestdb
db.user=hsdb
db.password=hsdbpass
9. Uso de bibliotecas externas
El uso de bibliotecas externas, más allá de las ya incluidas en el proyecto, no está permitido.
Debe tenerse en cuenta que para la evaluación se hará una compilación del código utilizando únicamente las bibliotecas que se incluyen en el proyecto por lo que, de utilizarse alguna biblioteca adicional, esta no estará disponible y fallará la construcción.
10. Parada del pool de hilos
El pool de hilos debe detenerse al final del método HybridServer.close()
, mediante una llamada al método shutdownNow
del pool, seguido de una llamada a awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)
.
Por ejemlo, suponiendo que hemos guardado en pool de hilos en una variable threadPool
de HybridServer
, deberíamos añadir los siguiente al final del método stop()
:
threadPool.shutdownNow();
try {
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}