feed twitter facebook LinkedIn facebook

Java » Recuperar la cabecera X-Forwarded-For

octubre 10, 2009 por Víctor Cuervo 5 Comentarios Imprimir Imprimir

X-Forwarded-For es una cabecera HTTP que nos permite conocer la IP origen de la petición. Y es que hasta ahora se utilizaba REMOTE_ADDR, la cual solo nos devolvía la IP de la última máquina por la que había pasado. A todas luces poco útil de cara a conocer el origen de la petición.

El formato de la cabecera X-Forwarded-For es el siguiente:

X-Forwarded-For: client1, proxy1, proxy2

En nuestro caso vamos a montar un servlet en Java que acceda a esta cabecera. Para acceder a los datos de la cabecera nos apoyaremos en el método .getHeader() del objeto HttpServletRequest. En este caso el nombre de la cabecera es "X-Forwarded-For", así que el código será el siguiente:

  1. String sIP = request.getHeader("X-FORWARDED-FOR");

Ahora, con esta ristra de datos podemos hacer lo que queramos. Posiblemente necesitemos apoyarnos en StringTokenizer para desmontar la cadena de IP. O, por lo menos, volcar el contenido a la pantalla:

  1. PrintWriter out = response.getWriter();
  2. out.print("La IP origen ha llegado por: " + sIP);

¿Conocías la existencia de X-Forwarded-For? ¿Crees que puede ayudarte en algo en tus programas?

Java » Recibir un parámetro numérico en una JSP

julio 30, 2009 por Víctor Cuervo 5 Comentarios Imprimir Imprimir

En el artículo Recibir parametros en una JSP veíamos como de una forma sencilla podíamos leer los parámetros que le llegan a una JSP.

El .getParameter("dato") y dejarlo en un String está muy bien. Pero, qué sucede si el dato que nos envían es un número (eso nos planteaba @Er)...

Pues la forma de hacerlo es muy sencilla. Para ello vamos a implementar una JSP a la cual le pasemos 2 datos numéricos, los cuales nos devolverá sumados.

Realmente la forma de recuperar los datos sigue siendo la misma que en Recibir parametros en una JSP. Es decir, utilizamos el método .getParameter("dato").

  1.  
  2. String datoUno = request.getParameter("dato1");
  3. String datoDos = request.getParameter("dato2");
  4.  

Lo que sucede es que tenemos que convertir los datos de tipo String en tipo numérico, por ejemplo en int. Para ello nos apoyaremos en la clase Integer y concretamente en el método .parseInt()

  1.  
  2. int uno = Integer.parseInt(request.getParameter("dato1"));
  3. int dos = Integer.parseInt(request.getParameter("dato2"));
  4.  

Pero qué sucede si el usuario no nos ha pasado un número en el parámetro. En este caso el método .parseInt() nos va a fallar, dándonos una NumberFormatException. Es por ello que tendremos que prevenir dicha excepción:

  1.  
  2. try {
  3. int uno = Integer.parseInt(request.getParameter("dato1"));
  4. int dos = Integer.parseInt(request.getParameter("dato2"));
  5.  
  6. } catch(NumberFormatException nfe) {
  7. out.println("Los datos recibidos no son números enteros");
  8. }
  9.  

Ahora solo nos quedará hacer la suma y mostrar el resultado en pantalla. En este caso convertimos un número en una cadena de caracteres mediante el método .toString(), también de la clase Integer.

Para mostrar los datos por pantalla utilizamos el método out.println(). Veamos como queda nuestro código:

  1.  
  2. try {
  3. int uno = Integer.valueOf(request.getParameter("dato1"));
  4. int dos = Integer.valueOf(request.getParameter("dato2"));
  5.  
  6. int suma = uno + dos;
  7.  
  8. out.println("La suma de " + datoUno + " + " + datoDos + " = " + Integer.toString(suma));
  9.  
  10.  
  11. } catch(NumberFormatException nfe) {
  12. out.println("Los datos recibidos no son números enteros");
  13. }
  14.  

Java » Obtener la IP que invoca al servlet

enero 12, 2008 por Víctor Cuervo 8 Comentarios Imprimir Imprimir

Mediante el siguiente código podremos recuperar la IP del usuario que está realizando la petición sobre el Servlet. Dadas todas las circunstancias que pueden rodear a la topología de las redes la IP que obtendremos no tiene porque ser la IP del usuario final, sino que fácilmente podría ser la IP de un proxy intermedio,... Es por ello que el ejemplo hay que utilizarle con fines didácticos y si lo usamos para producción, con un gran cuidado.

La IP de la máquina que invoca es una información que al servlet le llega en la petición, consecuentemente sus métodos doGet y doPost lo tendrán en el objeto HttpServletRequest.

Los métodos que nos permiten recuperar la información de la IP y el nombre de la máquina peticionaria son: getRemoteHost() y getRemoteAddr(). Simplemente les invocamos sobre el método HttpServletRequest.

  1. String ip = null; // IP del cliente
  2. String host = null; // Host del cliente
  3.  
  4. ip = request.getRemoteAddr();
  5. host = request.getRemoteHost();

Una vez obtenida la información, simplemente tendremos que devolverla por respuesta. Para ello nos apoyamos sobre los objetos PrintWriter y HttpServletResponse.

Veamos el código:

  1. PrintWriter out = response.getWriter();
  2. response.setContentType("text/html");
  3.  
  4. out.println("<html><head><title>Obtener IP del cliente</title></head><body>");
  5. out.println("<strong>Obtener la IP del cliente </strong>");
  6. out.println("La ip del cliente es " + ip + "<br>");
  7. out.println("El host del cliente es " + host);
  8. out.println("</body></html>");

Ver que el código que se devuelve en el stream de respuesta es una página web. De hecho, antes de devolver ninguna información indicamos que el content-type de respuesta es un "text/html".

Java » SingleThreadModel, concurrencia en servlet obsoleta

diciembre 29, 2007 por Víctor Cuervo Sin Comentarios Imprimir Imprimir

Podríamos describir el ciclo de vida de un Servlet, someramente, de la siguiente forma

Si el Servlet sobre el que se ha realizado una petición no está cargado en el contenedor web, este crea una instancia de la clase Servlet, ejecuta su método init y posteriormente dará servicio con alguno de los métodos de servicio: doGet, doPost, doPut,...

En el caso que el Servlet esté cargado en el contenedor, cuando llega la petición, simplemente se encamina dicha petición a los métodos de servicio: doGet, doPost, doPut,...

Como podemos ver la diferencia es que en el segundo caso no se ejecuta el método de inicialización.

Los métodos de servicio de los Servlet se ejecutaran de forma concurrente por cada petición que llegue al contenedor web. Esto implica que, en el caso de existir recursos compartidos, como por ejemplo las variables de sesión, estos podrán ser accedidos al mismo instante.

Hasta el API Servlet 2.4 existía el interface SingleThreadModel. Dicho interface aseguraba que solo existiría una instancia en un momento concreto gestionando una petición. De tal manera que, si llegaba otra petición en ese momento, esta era encolada y procesada posteriormente.

public class ServletNoConcurrente extends HttpServlet implements SingleThreadModel{
...
}

Si bien, este interface ha sido declarado obsoleto debido a varios puntos:

  1. Producía degradamiento del sistema.
  2. No evitaba el tener que realizar controles de concurrencia sobre los recursos compartidos, ya que aunque en la petición se aseguraba un solo hilo, no implicaba que en otro punto se estuviese accediendo al mismo recurso.

Podéis leer más sobre el interface SingleThreadModel en el API de Java.

Java » Mi primer servlet

diciembre 27, 2007 por Víctor Cuervo Sin Comentarios Imprimir Imprimir

En este ejemplo vamos a desarrollar nuestro primer Servlet, el cual nos de como respuesta la frase "Este es mi primer Servlet".

Crear el Servlet

La clase Java que implemente el Servlet deberá de extender la clase javax.servlet.HttpServlet.

  1. public class MiPrimerServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
  2. ...
  3. }

Dentro de esta clase tenemos que codificar, al menos, un método. El método doGet. Este método es el que se ejecuta cuando el Servlet recibe una petición del tipo GET (las más normales en Internet).

  1. public class MiPrimerServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
  2. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. ...
  4. }
  5. }

El método método doGet recibe dos parámetros: HttpServletRequest y HttpServletResponse. Estos dos parámetros representan el stream de petición y el stream de respuesta. Y ambos llevan los datos intrínsecos a la petición o respuesta.

Por ejemplo, si la petición viene con parámetros, estos los encontraremos en el objeto HttpServletRequest. De igual manera, si queremos establecer el tipo de contenido de respuesta, lo podremos hacer manipulando el objeto HttpServletResponse.

Para nuestro ejemplo de Mi primer Servlet, vamos a centrarnos en el objeto HttpServletResponse. Y es que lo que vamos a realizar será un volcado de datos sobre el flujo de salida.

Lo primero que haremos será el definir una clase PrintWriter a la que asociar el flujo de salida.

  1. out = response.getWriter();

Una vez establecida esta relación, lo primero que haremos será indicar el tipo de contenido que queremos volcar. En este caso, será una página web. Es por ello que el contenido será “text/html”. En otros casos podremos devolver otros mime-types como “images/jpeg” para las imágenes JPEG o “application/x-gzip” para los ficheros ZIP.

  1.  
  2. response.setContentType("text/html");

Ahora solo nos quedará ir invocando al método .println con el texto que conforme la página web.

  1. out.println("<html>");
  2. out.println("<head><title>Mi Primer Servlet </title></head>");
  3. out.println("<body>");
  4. out.println("<h1>Este es mi Primer Servlet</h1>");
  5. out.println("</body></html>");

Como se puede ver en el código, se vuelcan todas las etiquetas que conforman la página web HTML, body, title,… y nuestro texto.

Configurar el descriptor de despliegue

Una vez desarrollado y compilado nuestro servlet, tendremos que configurar el descriptor de despliegue. Este es el fichero web.xml. Dicho fichero indicará los servlets que hay desplegados en nuestra aplicación web y bajo que URL van a atender las peticiones.

Tendremos que definir dos etiquetas. La primera es la etiqueta servlet. Esta etiqueta sirve para definir el servlet. Tiene las siguientes etiquetas anidadas:

  • description, descripción del servlet
  • display-name, nome del servlet
  • servlet-class, clase del servlet. Con el nombre del paquete por delante.
  1. <servlet>
  2. <description>Mi primer Servlet</description>
  3. <display-name>MiPrimerServlet</display-name>
  4. <servlet-name>MiPrimerServlet</servlet-name>
  5. <servlet-class> aulambra.com.lineadecodigo.j2ee.servlets.MiPrimerServlet </servlet-class>
  6. </servlet>

Una vez definido el servlet, solo nos quedará realizar la asociación entre la URL que atenderá las peticiones del servlet y el servlet definido. Esto lo hacemos mediante la etiqueta servlet-mapping.

En ella encontramos dos etiquetas anidadas:

  • servlet-name, que es el nombre definido anteriormente.
  • url-pattern, que es el patrón de URL al que atenderá las petciones. En nuestro caso será /MiPrimerServlet.
  1. <servlet-mapping>
  2. <servlet-name>MiPrimerServlet</servlet-name>
  3. <url-pattern>/MiPrimerServlet</url-pattern>
  4. </servlet-mapping>

De esta manera, una vez desplegada la aplicación en un contenedor web, podremos acceder al servlet de la siguiente manera:

http://servidor:8080/nombre_app_web/MiPrimerServlet

Java » Recibir parámetros en un Servlet

diciembre 25, 2007 por Víctor Cuervo 10 Comentarios Imprimir Imprimir

A la hora de enviar información a un Servlet tenemos dos formas: mediante el método GET y mediante el método POST. Existen una serie de diferencias entre pasarlos de una forma u otra:

Metodo POST. Este método solo esta accesible desde los formularios. Se envían los parámetros de forma implícita junto a la página, es decir, al pasar los parámetros, nosotros no vemos reflejado en ningún sitio qué parámetros son y cual es su valor.

Método GET. Este método envía los parámetros de forma explicita junto a la página, mostrando en la barra de navegación los parámetros y sus valores. Son esas largas cadenas que aparecen en algunas páginas en nuestra barra de navegación, del estilo: buscar?id=1806&valor=0987&texto=todo&...

Las cadenas toman el aspecto parametro1=valor1&parametro2=valor2&....&parametroN=valorN. Es decir es una concatenación a través de & de pares parámetro-valor.

Preparando la página de envío

La página de envío será una simple página HTML. Lo primero que tenemos que hacer es montar las URL de envío. La URL está compuesta por el nombre del servidor, en nuestro caso localhost, el puerto (8080), el nombre de la aplicación web, en nuestro caso "lineadecodigo_j2ee" y el nombre del servlet.

Así la URL quedará de la siguiente forma:

http://localhost:8080/lineadecodigo_j2ee/RecibirParametros

La URL la montaremos en un formulario:

  1. <form action="http://localhost:8080/lineadecodigo_j2ee
  2. /RecibirParametros" method="post">
  3. <label for="texto1">Texto 1</label><input type="text" id="texto1" name="texto1" size=20><br>
  4. <label for="texto2">Texto 2</label><input type="text" id="texto2" name="texto2" size=20>
  5. <input type="submit" value="Enviar">
  6. </form>

y en un enlace:

<a href="http://localhost:8080/lineadecodigo_j2ee/RecibirParametros?texto1=lineadecodigo&texto2=imagen">Mandar parametros por GET</a>


Codificando el Servlet

Lo primero que hay que saber es que la clase que implemente el Servlet extiende de HttpServlet. Así el código será el siguiente:

  1. public class RecibirParametros extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
  2. ...
  3. }

Dentro del Servlet hay dos métodos importantes: doGet y doPost. Estos métodos son los que atienden las peticiones POST y GET de la página, respectivamente.

  1. public class RecibirParametros extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
  2.  
  3. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. ...
  5. }
  6.  
  7. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. ...
  9. }
  10. }

Ambos métodos reciben como parámetros los datos de la petición HttpServletRequest y el flujo de la salida de respuesta HttpServletResponse.

Podemos codificar los dos métodos para hacer cosas diferentes si viene una petición POST u otra GET. O bien, como en nuestro caso, encaminar una petición a la otra para tratarlas de una misma forma.

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. doPost(request,response);
  3. }

Para recibir los parámetros nos vamos a apoyar en el objeto HttpServletRequest y en concreto en el método .getParameter(). En este método indicaremos el nombre del parámetro que queremos recuperar.

  1. String parametro1 = request.getParameter("texto1");
  2. String parametro2 = request.getParameter("texto2");
  3.  

En este caso los parámetros se llaman texto1 y texto2.

Lo siguiente que haremos será montar la respuesta. Ahora nos apoyaremos en el objeto HttpServletResponse. Mediante el método .getWriter() obtendremos el stream de salida. Esto lo manejamos mediante el objeto PrintWriter.

  1. out = response.getWriter();

Antes de empezar a volcar texto en el flujo de salida tenemos que indicar el tipo de contenido que se vuelca. En este caso es "text/html". Es lo que se denomina content-type.

  1. response.setContentType("text/html");

Ahora solo quedará el ir volcando información mediante métodos .println(). El cual tiene como parámetro el texto a volcar a la página.

  1. out.println("<html>");
  2. out.println("<head><title>Enviar parametros a un Servlet</title></head>");
  3. out.println("<body>");
  4. out.println("<h1>Enviar parametros a un Servlet</h1>");
  5. out.println("La primera palabra pasada como parámetro es <strong>" + parametro1 + "</strong><br>");
  6. out.println("La segunda palabra pasada como parámetro es <strong>" + parametro2 + "</strong>");
  7. out.println("</body></html>");

Java » Recibir parametros en una JSP

diciembre 27, 2006 por Víctor Cuervo 41 Comentarios Imprimir Imprimir

Una página JSP nos permite combinar la tecnología de las páginas web con la tecnología de las páginas de servidor.

Es por ello que en una página JSP siempre veremos dos partes bien diferenciadas. El código relativo a la tecnología cliente: HTML, XHTML, SVG,... y lo que denominaremos scriptlet. Estos scriptlet no deja de ser código Java que se ejecutará en el lado del servidor para añadirse al código cliente ya existente.

Es decir, el navegador que ejecute nuestra JSP solo verá una página web (sea la tecnología que sea). Dicha página web se habrá compuesto en el servidor mediante código Java y código cliente.

Una de las primera cosas que querremos hacer será pasarle información a esta página. Lo primero que conocer son las formas de pasar información a una página web (vía POST y vía GET). Las diferencias, a grandes rasgos, son que las peticiones vía GET encadenan los valores a pasar a la página web en la URL, mientras que si hacemos una petición vía POST se pasará la información de forma implícita.

En el primer caso veremos URL del tipo...

ObtenerParametros.jsp?dato1=pagina&dato2=lineadecodigo

Lógicamente nuestro cometido será el recuperar la información que llega como parámetro para utilizarla dentro de nuestra página web.

Dentro del contexto de la página JSP tenemos disponible la variable request. Dicha variable viene a representar la petición que es recibida en la página. Y consecuentemente los parámetros y valores que la llegan.

Si queremos recuperar el valor de los parámetros, simplemente deberemos de utilizar el método .getParameter(String parametro). Donde indicaremos el nombre del parámetro a recuperar.

Así, en la anterior petición podremos recuperar los valores de los parámetros dato1 y dato2 mediante la siguiente linea de codigo:

  1. String datoUno = request.getParameter("dato1");
  2. String datoDos = request.getParameter("dato2");

Ahora solo nos quedará el utilizar los valores de los datos recibidos como parámetro donde y como queramos. Por ejemplo para, simplemente, mostrarlos por pantalla.

  1. out.println(datoUno);
  2. out.println(datoDos);

En este caso hemos utilizado la variable out, que viene a representar la respuesta hacia el cliente y en concreto el método .println(variable) que vuelca información sobre la página.

Java » Redirigir todas las JSP a un Servlet

noviembre 30, 2006 por Víctor Cuervo 5 Comentarios Imprimir Imprimir

Ciertos modelos de arquitectura son participes de evitar el acceso directo a las páginas JSP para poder hacer ciertas validaciones. Esto implica que cada vez que alguien ponga una URL sobre nuestro sitio con *.jsp sea reenviado a un Servlet.

Esto lo podemos hacer de una forma muy sencilla modificando los mapping del descriptor de despliegue de la aplicación Web que estemos montando. El descriptor de despliegue es el fichero /WEB-INF/web.xml

Para ello bastará con que sepamos como hacer un mapping. Esto se puede hacer de forma sencilla modificando el patrón de URL a interceptar.

Así, el mapping tiene dos etiquetas <servlet-name> donde irá el nombre del servlet que atenderá la peticióny <url-pattern> donde le indicaremos el patrón de URL que queremos interceptar. En nuestro caso *.jsp.

De esta manera el código nos quedaría de la siguiente forma:

  1. <servlet-mapping>
  2. <servlet-name>Controller</servlet-name>
  3. <url-pattern>*.jsp</url-pattern>
  4. </servlet-mapping>

Será el servlet Controller el que reciba todas las peticiones sobre las JSP.

Java » Crear un mapping a un servlet

noviembre 14, 2006 por Víctor Cuervo 3 Comentarios Imprimir Imprimir

El proceso de puesta en servicio de un servlet podríamos resumirlo en dos pasos. El primero de ellos es crear el servlet. Para ello implementaremos una clase java que extienda de HttpServlet, la cual implementará la funcionalidad de negocio que estemos resolviendo.

Pero de nada nos sirve el crear un servlet si no lo publicicamos al exterior. Este mecanismo de publicación es lo que se conoce como mapping.

La idea del mapping es la de asociar una URL o un patrón de una URL a un servlet.

Para ello deberemos de configurar el descriptor de despliegue de la aplicación. Este es el fichero que encontramos en /WEB-INF/web.xml

En este fichero necesitaremos de la etiqueta <servlet-mapping>. Esta etiqueta nos permitirá definir un nuevo mapping. Anidado a esta etiqueta encontramos dos: la primera especificará el nombre del servlet sobre el que queremos establecer el mapping <servlet-name>, mientras que la segunda especificará sobre que URL se realiza el mapping <url-pattern>.

<servlet-mapping>
  <servlet-name>MiServlet</servlet-name>
  <url-pattern>/URLDelServlet</url-pattern>
</servlet-mapping>

Con este mapping toda las peticiones que se hagan a la URL http://miservidor/URLDelServet serán procesadas por el Servlet "MiServlet".

Java » Modificar time-out de sesión

noviembre 12, 2006 por Víctor Cuervo 9 Comentarios Imprimir Imprimir

Cuando un usuario realiza una conexión contra una aplicación web se le crea una sesión. La sesión es la identidad que tiene dicho usuario en el servidor hasta que se desconecta.

En la sesión de un usuario se podrá almacenar información que queramos que previva mientras el usuario permanezca conectado a nuestra web.

Y esta última frase es el kit de la cuestión. ¿Cúando sabemos que un usuario se ha desconectado? Pues es difícil, ya que el protocolo HTTP es sin estado y las peticiones vienen y van sin un control. Es por ello que la única forma de saber que un usuario se ha ido es indicando un tiempo de caducidad de la sesión, más conocido como timeout de sesión.

Dependiendo del contenedor de servlets que estemos utilizando, este establecerá el timeout de sesión en un valor u otro atendiendo a unos parámetos de configuración.

Por ejemplo, Tomcat utiliza el fichero /conf/web.xml para configurarla, como podemos ver en estas líneas de código:

<!-- ==== Default Session Configuration ==== -->
<!-- You can set the default session timeout (in minutes) for all newly   -->
<!-- created sessions by modifying the value below.                       -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>

Como vemos, establece 30 minutos como tiempo máximo de inactividad.

Pero cuando creemos una aplicación podemos indicar un tiempo de timeout sobre esta aplicación. Y es que quien no nos dice que nuestra aplicación pueda correr sobre varios contenedores de servlets.

Para configurar el timeout de la sesión de nuestra aplicación deberemos de configurar el descriptor de despliegue de la misma (/WEB-INF/web.xml). Para ello utilizremos la etiqueta < session-config> y anidada a ella <session-timeout>. Vamos, que son las mismas etiquetas que utiliza Tomcat.

Así, el código nos quedaría de la siguiente forma:

<session-config>
<session-timeout>10</session-timeout>
</session-config>

En este caso establecemos el tiempo de timeout a 10 minutos.