Cliente HTTP en Java

Anuncio
Cliente HTTP en Java
Objetivos

Desarrollar, usando Java, un cliente básico del protocolo web que permita enviar
una solicitud HTTP a un servidor web y procesar la respuesta.
Requerimientos de la aplicación:
La aplicación cliente básico de web debe:
- Obtener la información del URL que se usará para hacer la petición web
- Abrir una conexión al servidor (dominio) seleccionado por el usuario por medio de un
socket.
- Escribir en el socket (enviar al servidor) un mensaje de petición HTTP por medio de un
PrintWriter del OutputStream sobre el socket
- Leer el mensaje de respuesta, realizar un procesamiento mínimo de los encabezados y
descargar en un archivo el cuerpo de la respuesta
Diagrama de clases
Como propuesta de solución se ha definido un conjunto de clases para procesar las peticiones.
HttpClient
Es la clase que coordina (controla) el funcionamiento de la
aplicación. Básicamente, esta clase realiza la conexión por un
socket al servidor web, invoca al RequestProcessor para enviar
el mensaje de solicitud al servidor e invoca al
ResponseProcessor para obtener y procesar el mensaje de
respuesta.
RequestProcessor
Esta clase envía el mensaje de solicitud al servidor web. El
método sendRequestMessage recibe como parámetro un
OutputStream que es usado para enviar la solicitud.
ResponseProcessor Esta clase obtiene y procesa el mensaje de respuesta. El método
processResponse recibe como parámetro un InputStream que
es usado para leer el mensaje.
Instrucciones Paso a paso
1. El cliente se debe conectar al servidor por medio de un socket.
2. El usuario debe indicar la petición HTTP que el cliente envía al servidor.
3. El cliente retorna como respuesta un mensaje HTTP con las siguiente estructura:
4. El programa debe leer el mensaje de respuesta, byte por byte, usando un buffer de
Entrada. Cada byte del buffer representa un carácter. Como el objetivo es descargar
únicamente el cuerpo del mensaje de respuesta, el programa puede importar todos los
encabezados de la respuesta. El programa puede buscar el renglón vacío para reconocer
el final de los encabezados.
a. Los caracteres de fin de línea (es decir, los caracteres <CR><LF>) pueden
leerse en java usando el texto “\r\n”. Para identificar el fin de los encabezados, el
programa puede buscar el punto en donde esta secuencia se encuentre dos
veces (es decir, el final de los encabezados del mensaje y el renglón vacío). A
partir de ese punto, el texto corresponde con el cuerpo del mensaje que se debe
guardar.
5. El programa debe guardar el cuerpo del mensaje en un archivo, con el nombre que
indique el usuario.
Creación del proyecto
Estructura general del proyecto
El proyecto base se entrega con la siguiente estructura:
HttpClient
|
---src
|
|
|
------client
|
|
|
|
|
-------HttpClient.java
|
|
|
|
|
-------RequestProcessor.java
|
|
|
|
|
-------ResponseProcessor.java
|
|
|
---------ui
|
|
|
|
|
-------ClientUI.java
|
---JRE System Library
|
---descarga
La clase RequestProcessor.java
La responsabilidad de esta clase es enviar, por medio del socket, la petición al servidor
web. Ésta clase es un Singleton, tiene un atributo donde vamos a guardar el histórico de
peticiones realizadas desde el cliente web. Para enviar la petición contamos con el
método sendRequestMessage que recibe como parámetros el OutputStream del
socket, el mensaje y el host. Complete el método con las siguientes instrucciones:
public void sendRequestMessage(OutputStream output, String message, String host)
throws IOException{
output.write((message+"\r\n").getBytes());
output.write(("Host:"+host+"\r\n").getBytes());
output.write("\r\n".getBytes());
output.write("\r\n".getBytes());
output.flush();
historic.add(host + " - " + message);
}
La clase ResponseProcessor.java
La responsabilidad de esta clase es procesar la respuesta del servidor, la clase es un
Singleton y procesa la respuesta por medio del método RequestProcessor que recibe
como parámetros el InputStream y el nombre del archivo donde se quiere guardar el
cuerpo del mensaje.
La idea del proceso es leer el archivo Byte por Byte, debe buscar la secuencia “\r\n\r\n”
que indica el fin del encabezado del mensaje y el inicio del cuerpo que debe guardar en
un archivo con el nombre ingresado por el usuario. El archivo debe ser ubicado en la
carpeta “descarga” en la raíz del proyecto. Complete el método con las siguientes
instrucciones:
public File processResponse(InputStream input, String fileName) throws IOException{
byte[] buffer = new byte[1024];
File file = new File("descarga/"+fileName);
BufferedOutputStream bOutput
= new BufferedOutputStream(new FileOutputStream(file));
int
int
int
int
int
tReaded = 0;
tArchivo = 0;
tReadedi = 0;
tPatterns = 0;
tWaitedChar = '\r';
boolean inContent = false;
//En cada paso del ciclo lee la entrada y lo guarda en el array buffer,
//el ciclo sigue si el numero de bytes es mayor que 0
while((tReadedi = input.read(buffer))>0){
if(inContent){
// A este bloque entra una vez ha encontrado
// el inicio del mensaje.
bOutput.write(buffer,0,tReadedi);
tArchivo += tReadedi;
}
else {
//buscamos en el buffer el patron '\r\n\r\n'
// y guardamos en caso de encontrarlo
for(int i=0; i<tReadedi; i++){
int chari = buffer[i];
if(chari==tWaitedChar){
if(chari=='\r'){
tWaitedChar='\n';
}
else if(chari=='\n'){
tPatterns++;
tWaitedChar='\r';
}
inContent = tPatterns==2;
if(inContent){
//Entrar a esta parte significa
// que encontramos '\r\n\r\n'
//Guardamos el buffer desde la posición i+1
bOutput.write(buffer,i+1,tReadedi-(i+1));
tArchivo+=tReadedi-(i+1);
break;
}
}
else {
tPatterns = 0;
tWaitedChar = '\r';
}
}
}
tReaded += tReadedi;
buffer = new byte[1024];
}
bOutput.close();
return file;
}
La clase HttpClient
La responsabilidad de esta clase es gestionar la conexión con el servidor y coordinar el envío del
mensaje y la recepción de la respuesta. En su constructor recibe el host y el puerto de conexión
para iniciarla.
El método processRequest recibe como parámetros el mensaje de la petición, el host y el
nombre del archivo, gestiona las clases RequestProcessor y ResponseProcessor para
guardar el cuerpo de la petición y retorna como respuesta el archivo guardado.
Descargar