Menú
Está libre
registro
hogar  /  SOBRE/ Escribir un servlet para espiar a los usuarios de las redes sociales. Java

Escribir un servlet para espiar a los usuarios de las redes sociales. Java

Los servlets son programas Java que se ejecutan en el lado del servidor de una aplicación web. Así como los subprogramas amplían dinámicamente la funcionalidad de un navegador web, los servlets amplían dinámicamente la funcionalidad de un servidor web. Si bien los servlets pueden atender cualquier solicitud, se usan comúnmente para extender servidores web. Para tales aplicaciones, la tecnología Java Servlet define clases de servlet específicas de HTTP. Los paquetes javax.servlet y javax.servlet.http proporcionan interfaces y clases para crear servlets.

  • ¿Cuál es la estructura de un proyecto web?

  • ¿Qué es un contenedor de servlets? Ciclo de vida del servlet.

Un contenedor de servlets es un programa que gestiona el ciclo de vida de los servlets.
Ciclo de vida del servlet: es administrado por el contenedor del servlet, la primera vez que se accede al servlet, se carga en la memoria y se llama al método init (). En toda la aplicación, se llama al método service () para manejar las solicitudes de los clientes. Cuando la aplicación termina, se llama al método destroy () y el servlet se descarga de la memoria.

  • ¿Cuáles son las tareas, la funcionalidad del contenedor de servlets?

Un contenedor de servlets puede actuar como un servidor web independiente completo, servir como proveedor de páginas para otro servidor web como Apache o integrarse en un servidor de aplicaciones Java EE. Proporciona intercambio de datos entre el servlet y los clientes, se encarga de funciones tales como crear un entorno de software para un servlet en funcionamiento, identificar y autorizar clientes, organizar una sesión para cada uno de ellos.

  • ¿En qué se diferencia sendRedirect () de forward ()?

El método forward () se usa para llamar a una JSP usando una ruta relativa, y el método sendRedirect () se usa para hacer referencia a una JSP usando una ruta absoluta. La diferencia entre estos métodos es que un objeto de solicitud existente se pasa con el método forward () y se genera una nueva solicitud cuando se llama al método sendRedirect (). En este último caso, la información debe transferirse con otros objetos. Además, el método forward () es más rápido.

  • ¿Qué sabes sobre los filtros de servlets?

La implementación de la interfaz de Filtro le permite crear un objeto que intercepta la solicitud, puede transformar el encabezado y el contenido de la solicitud del cliente. Los filtros no crean una solicitud o respuesta, solo las modifican. El filtro preprocesa la solicitud antes de que llegue al servlet y luego (si es necesario) procesa la respuesta que proviene del servlet. El filtro puede interactuar con diferentes tipos de recursos, en particular, y con servlets y páginas JSP. Los filtros de servlet pueden:

  • interceptar el inicio del servlet antes de que se inicie el servlet.
  • determinar el contenido de la solicitud antes de que se inicie el servlet.
  • modificar los encabezados de solicitud y los datos en los que se empaqueta la solicitud entrante.
  • modificar los encabezados de respuesta y los datos en los que se empaqueta la respuesta recibida.
  • interceptar el inicio de un servlet después de una llamada al servlet.

Se puede configurar un filtro de servlet para que funcione con un solo servlet o grupo de servlets. La base para generar filtros es la interfaz javax.servlet.Filter, que implementa tres métodos:

  • void init (FilterConfig config) lanza ServletException;
  • anular destruir ();
  • void doFilter (solicitud ServletRequest, respuesta ServletResponse, cadena FilterChain) lanza IOException, ServletException;

El método init () se llama antes de que el filtro comience a ejecutarse y configura el objeto de configuración del filtro. El método doFilter hace el trabajo real del filtro. Por lo tanto, el servidor llama a init () una vez para iniciar el filtro, y luego llama a doFilter () tantas veces como solicitudes se hagan directamente a este filtro. Una vez que el filtro termina su trabajo, se llama al método destroy ().

  • ¿Por qué necesita oyentes en los servlets?

Los oyentes de contexto y sesión son clases que pueden realizar un seguimiento de cuándo se inicializó un contexto o sesión, o realizar un seguimiento de cuándo deben destruirse y cuándo se agregaron o eliminaron atributos del contexto o sesión. Servlet 2.4 amplía el modelo de escucha de solicitudes al permitirle rastrear cómo se crea y destruye una solicitud, y cómo se agregan y eliminan atributos del servlet. Se han agregado las siguientes clases en Servlet 2.4:

  • ServletRequestListener
  • ServletRequestEvent
  • ServletRequestAttributeListener
  • ServletRequestAttributeEvent

  • ¿Cómo manejo las excepciones lanzadas por otro servlet en la aplicación?

Dado que el navegador solo entiende HTML, cuando la aplicación lanza una excepción, el contenedor de servlets manejará la excepción y generará una respuesta HTML. Esto es similar a lo que sucede con los códigos de error como 404, 403, etc. La API de Servlet proporciona soporte para nuestros propios servlets para manejar excepciones y errores, que podemos especificar en el descriptor de implementación. La tarea principal de estos servlets es manejar el error o la excepción y enviar una respuesta HTML clara al usuario. Por ejemplo, puede proporcionar un enlace a la página principal, así como una descripción de algunos detalles sobre el error.

  • ¿Qué es un descriptor de implementación?

El descriptor de implementación es un archivo de configuración de artefactos que se implementará en el contenedor de servlets. En la especificación de Java Platform, Enterprise Edition, un descriptor de implementación describe cómo se debe implementar un componente, módulo o aplicación (como una aplicación web o empresarial).

Este archivo de configuración especifica las opciones de implementación para un módulo o aplicación con configuraciones específicas, opciones de seguridad y describe los requisitos de configuración específicos. La sintaxis de los archivos descriptores de implementación es XML.

  • ¿Cómo implemento un lanzamiento de servlet con el lanzamiento de una aplicación?

El contenedor de servlet generalmente carga el servlet en la primera solicitud del cliente, pero a veces es necesario cargar el servlet justo al inicio de la aplicación (por ejemplo, si el servlet es voluminoso y tardará mucho en cargarse). Para hacer esto, necesita usar el elemento load-on-startup en el descriptor (o la anotación loadOnStartup), que indicará si el servlet debe cargarse al inicio.

El valor debe ser int. Si el valor es negativo, el servlet se cargará a petición del cliente, y si es 0 y más, se cargará al inicio de la aplicación. Cuanto menor sea el número, antes estará el servlet en la cola de descarga.

  • ¿Qué es el objeto ServletConfig?

La interfaz javax.servlet.ServletConfig se utiliza para pasar información de configuración a un servlet. Cada servlet tiene su propio objeto ServletConfig, que el contenedor de servlet es responsable de instanciar. Los parámetros de inicio en web.xml (o anotaciones de WebInitParam) se utilizan para establecer los parámetros de configuración. El método getServletConfig () se usa para obtener el objeto ServletConfig para este servlet.

  • ¿Qué es el objeto ServletContext?

La interfaz javax.servlet.ServletContext define una serie de métodos que utiliza un servlet para comunicarse con su contenedor de servlet, como obtener el tipo MIME de un archivo, enviar solicitudes o escribir en un archivo de registro. El objeto ServletContext es único y está disponible para todos los servlets en una aplicación web. Podemos usar el objeto ServletContext cuando necesitamos proporcionar acceso a uno o más servlets a los parámetros inicializados de la aplicación web. Para hacer esto, use el elemento en web.xml. El objeto ServletContext se puede obtener utilizando el método getServletContext () de la interfaz ServletConfig.

Los contenedores de servlets también pueden proporcionar objetos de contexto que son exclusivos de un grupo de servlets. Cada uno de los grupos se asociará con un conjunto diferente de URL de ruta de host.

ServletContext se ha ampliado en la especificación de Servlet 3 y proporciona la adición programática de oyentes y filtros a su aplicación. Esta interfaz también tiene muchos métodos útiles como getMimeType (), getResourceAsStream (), etc.

  • ¿Cuál es la diferencia entre ServletContext y ServletConfig?

A continuación se muestran algunas de las diferencias:

  • ServletConfig es un objeto único para cada servlet, mientras que ServletContext es único para toda la aplicación.
  • ServletConfig se utiliza para proporcionar parámetros de inicialización al servlet y ServletContext se utiliza para proporcionar parámetros de inicialización de la aplicación para todos los servlets.
  • No tenemos la capacidad de establecer atributos en el objeto ServletConfig, mientras que podemos establecer atributos en el objeto ServletContext que estarán disponibles para otros servlets.

  • Interfaz ServletResponse.

La interfaz ServletResponse es una herramienta para enviar datos al cliente. Todos los métodos de esta herramienta sirven exactamente para este propósito.

  • Interfaz ServletRequest.

La interfaz ServletRequest es una herramienta para obtener parámetros de solicitud HTTP. Esta interfaz tiene varios métodos que son idénticos en nombre y propósito a ServletContext.

  • ¿Qué es Request Dispatcher?

La interfaz RequestDispatcher se usa para pasar una solicitud a otro recurso (esto podría ser HTML, JSP u otro servlet en la misma aplicación). Podemos usar esto para agregar contenido de otro recurso a la respuesta. Esta interfaz se utiliza para la comunicación interna entre servlets en el mismo contexto. Hay dos métodos implementados en la interfaz:

  • void forward (ServletRequest var1, ServletResponse var2): reenvía una solicitud del servlet a otro recurso (servlet, archivo JSP o HTML) en el servidor.
  • void include (ServletRequest var1, ServletResponse var2): incluye contenido de recursos (Servlet, JSP o página HTML) en respuesta.

Se puede acceder a la interfaz mediante el método getRequestDispatcher (String s) de ServletContext. La ruta debe comenzar con /, que se interpretará como relativa a la ruta raíz actual del contexto.

  • ¿Cómo se puede crear un interbloqueo en un servlet?

Se puede obtener un interbloqueo implementando una llamada de método en bucle, por ejemplo, llamando al método doPost () en el método doGet () y llamando a doGet () en el método doPost ().

  • ¿Cómo obtengo la dirección del servlet en el servidor?

Para obtener la ruta real del servlet en el servidor, puede usar esta construcción: getServletContext (). GetRealPath (request.getServletPath ()).

  • ¿Cómo obtengo información del servidor de un servlet?

La información del servidor se puede obtener usando el objeto ServletContext usando el método getServerInfo (). Aquellos. getServletContext (). getServerInfo ().

  • ¿Cómo obtener la dirección IP del cliente en el servidor?

Utilice request.getRemoteAddr () para obtener la ip del cliente en el servlet.

  • ¿Qué sabe acerca de las clases de envoltura de servlets?

La API HTTP de Servlet proporciona dos clases contenedoras, HttpServletRequestWrapper y HttpServletResponseWrapper. Ayudan a los desarrolladores a implementar sus propias implementaciones de los tipos de servlet de solicitud y respuesta. Podemos extender estas clases y anular solo los métodos necesarios para implementar nuestros propios tipos de objetos de respuesta y solicitud. Estas clases no se utilizan en la programación de servlets estándar.

Han pasado casi veinte años desde la llegada del lenguaje de programación Java. Durante este tiempo, Java profetizó la muerte y el olvido, los programadores en el terreno se rieron de su inhibición y codicia por los recursos. Pero también hubo quienes creyeron en Java, desarrollaron todo tipo de bibliotecas, desarrollaron la comunidad, demostraron persistentemente que no hay límites para Java: en tiempo real, integrado, IA, todo es posible. Decidimos no quedarnos al margen y hacer una pequeña serie de artículos sobre Java en esta sección. ¡Ir!

Tu hervidor elige Java

Según el propio Oracle, la máquina virtual Java está instalada actualmente en más de tres mil millones de dispositivos. Y estos no son solo computadoras y teléfonos inteligentes, sino también cámaras, televisores, reproductores de Blu-ray, impresoras, tarjetas SIM, cajeros automáticos e incluso automóviles. La lista crecerá de manera constante y, con ella, las ofertas de los empleadores para los programadores de Java. Incluso ahora, el número de vacantes para programadores de Java supera al resto. Y las empresas están dispuestas a pagar cada vez más, cazando empleados y organizando mejores condiciones laborales.

¿Y para qué sirve?

Los programadores de Java se sienten atraídos por el minimalismo de la sintaxis. Sin modificadores innecesarios ni palabras de servicio. Incluso la ausencia de herencia múltiple, que al principio confundió un poco a los programadores de C ++, resulta ser razonable y justificada al final. Lógica simple, administración automática de memoria, documentación detallada, foros con respuestas a todo tipo de preguntas, código abierto: todo esto le permite profundizar rápidamente en el proceso de desarrollo y reduce significativamente la cantidad de errores potenciales. Incluso los campesinos indios aprenden Java en un par de meses, al menos eso es lo que dicen sus diplomas :). Además, Java es un lenguaje interpretado. El compilador traduce el código fuente en el llamado código de bytes, que es fácil de volver a convertir, lo que hace que Java sea especialmente atractivo para la ingeniería inversa.

Bueno, empecemos

Java es un lenguaje orientado a objetos, lo que significa que todas las variables, métodos y constantes se declaran dentro de una clase. Además de las clases, también hay interfaces, una construcción abstracta especial que le permite describir el comportamiento de un objeto sin especificar una implementación específica. Y si no hay herencia múltiple de clases en Java, entonces una clase puede implementar cualquier número de interfaces, lo que permite que un objeto tenga muchas funciones, pero proporciona solo una parte de ellas.

Los tipos de datos se pueden dividir en dos grupos: simple (int, long, char, etc.) y objeto: clases, interfaces, matrices. Los tipos simples son siempre y en todas partes de dimensión fija. Por ejemplo, en cualquier arquitectura y dispositivo, un int ocupa cuatro bytes de memoria. Esto es muy útil para los cálculos. La matriz de datos contiene una longitud de atributo especial, que almacena el tamaño de la matriz, por lo que agradecemos especialmente a los desarrolladores. Los diferentes tipos de datos se pasan a los métodos de diferentes formas. Los tipos simples siempre se pasan por valor. Objeto: siempre por referencia para ahorrar memoria. Esto significa que si pasamos int a = 10 y cambiamos su valor a 5 en el método llamado, entonces en el método original a seguirá siendo 10. Pero si cambiamos la propiedad del objeto, entonces cambiará en el método original. así como.

Recuerda el recuerdo

Aunque un programador de Java se libera de la necesidad de asignar y liberar memoria, el desconocimiento de algunas de las peculiaridades de la máquina virtual y el recolector de basura pueden convertir fácilmente su programa en un monstruo insaciable que devora el tiempo de la CPU y toda la memoria disponible.

Al crear una nueva matriz, recuerde siempre que es mucho más fácil crear muchos trozos pequeños de memoria que uno enorme. De lo contrario, corre el riesgo de encontrarse con un error de memoria insuficiente, lo que aproximadamente significa que tenía memoria, pero salió todo.

Muchos programadores, cuando cambian a Java y aprenden acerca de la limpieza automática de memoria, comienzan a crear objetos en grandes cantidades, con la esperanza de que todo esto se aclare por sí solo. Mientras tanto, un recolector de basura es como una máquina que puede recoger basura que solo se tira en un bote de basura cerca de una casa. Si ya no necesita algunos datos, no debe almacenarlos por si acaso, como un montón de postales antiguas: asigne el puntero a los datos nulos, ayude al limpiador a limpiar :). También es una buena práctica dejar clara la lista si aún no la necesita. Recuerde, el objeto se mantendrá en la memoria siempre que haya referencias a él en el código. Incluso si su programa se ejecuta en 16 gigabytes de memoria y no amenaza con fallar con Memoria insuficiente, se volverá cada vez más torpe y lento debido al exceso de memoria utilizada. El 99% de las quejas de los usuarios sobre los programas Java lentos se deben a un código fuente escrito de manera ineficaz. Si necesita crear constantemente objetos que se usan rápidamente y ya no son necesarios, por ejemplo, muchos mensajes pequeños, considere la posibilidad de crear un grupo que almacene varias instancias para uso repetido. Recuerde, crear y eliminar un objeto es costoso.

Por la causa, señores

Un ejemplo es mejor que mil palabras. Puede hojear el manual y ver los Hellowords estándar sin nosotros, por lo que asumiremos que ya lo ha hecho y está listo para implementar un ejemplo más interesante.

Tú y yo nos encargaremos de la aplicación servidor de Java y escribiremos un pequeño programa para "espiar" a los usuarios de las redes sociales. Para hacer esto, ni siquiera tiene que encontrar un trabajo en la NSA: los usuarios se lo transmiten todo a sí mismos, y solo tendremos que obtener esta información, organizarla y mostrarla de manera hermosa. Tomemos uno de los servicios sociales populares, por ejemplo, foursquare, y dibujemos el movimiento de nuestros amigos en un mapa.

Primero, veamos qué podemos sacar de foursquare. Después de pasar por las páginas del desarrollador, dirigimos nuestra atención a dos métodos:

  • https://developer.foursquare.com/docs/users/checkins: lugares visitados por el usuario. Lamentablemente, hasta ahora solo es compatible con el usuario registrado en el programa, y ​​hay rumores de que por restricciones de implementación seguirá siéndolo;
  • https://developer.foursquare.com/docs/checkins/recent: lugares visitados por amigos del usuario registrado. Si juegas un poco con esta función, entonces queda claro un hecho triste: por cada amigo se devuelve exactamente un lugar: el último en el que se registró.

Para utilizar la API de foursquare, debe registrar nuestra futura aplicación, vaya a esta dirección: https://en.foursquare.com/developers/register y complete los campos (sí, tendrá que registrarse en foursquare, pero puedes hacerlo bien sin mí).

De los campos importantes aquí, puede marcar solo "Nombre de la aplicación", "URL de la página de descarga / bienvenida" (ingrese una dirección web arbitraria aquí) y "Redirigir URI (s)": esta es la dirección a la que el servidor nos enviará después del registro. Escribiremos el valor deseado aquí más adelante, pero por ahora solo puede ingresar cualquier dirección web. Haga clic en "Guardar" y nuestra aplicación de seguimiento se ha registrado correctamente.

Subiendo a las nubes

Captain Obvious transmite que cualquier aplicación de servidor requiere un servidor para ejecutarse. Levante el servidor usted mismo las hemorroides, por lo que usaremos las ahora populares soluciones en la nube. La nube estará patrocinada por Google Corporation, porque su Google App Engine es gratuito, bastante fácil de configurar y usar. Primero, vaya aquí y descargue el SDK de Google App Engine para Java.

Ahora puedes empezar a crear tu proyecto. Para el desarrollo de Java, uso IntelliJ IDEA, pero puede usar el entorno Eclipse gratuito e igualmente conocido.

Seleccionemos un nuevo proyecto Java. Llamémoslo nsa_tracker.


En la siguiente pestaña, marque la aplicación web y Google App Engine a la izquierda e indique la ruta al SDK de App Engine descargado y descomprimido anteriormente.


Ahora siéntese y deje que el IDE haga lo suyo. Si eligió IDEA e hizo todo correctamente, como resultado verá un proyecto terminado que, cuando se inicia, abre una ventana del navegador con contenido vacío. Puedes empezar a codificar.

Empezamos a buscar

Entonces, tenemos una carpeta con un proyecto, que contiene la carpeta src. Pondremos las fuentes allí. Las fuentes de Java están agrupadas por paquete. Un paquete es una carpeta en el disco. Los paquetes son necesarios para no apilar todas las fuentes en un montón, sino para separarlas, guiadas por los principios de la lógica. Por ejemplo, sería lógico colocar el código relacionado con la interfaz de usuario en el paquete ui y las interacciones de red en el paquete de red. Esto facilita enormemente el desarrollo y soporte del proyecto posteriormente. Históricamente, ha sido la práctica comenzar la estructura del paquete con el nombre de la empresa seguido del nombre del programa. Esto ayudará a identificar fácilmente nuestras fuentes entre el montón de las mismas en el futuro. Para nuestro programa, crearemos el paquete org.nsa.tracker. En él crearemos clases.

Los servlets se utilizan en el servidor para procesar las solicitudes de los usuarios. Un servlet es una clase que generalmente hereda de HttpServlet y opera sobre una base de solicitud-respuesta. Todo lo que necesita es anular el método doGet. A pedido del usuario, debemos iniciar sesión en foursquare, descargar la lista de registros de amigos y redirigir la solicitud a la página con el mapa.

Para trabajar con la API de foursquare, usaremos la biblioteca gratuita foursquare-api-java, que se puede obtener desde aquí. La biblioteca Java es un archivo ZIP con una extensión jar que contiene clases Java compiladas que implementan una funcionalidad específica. Para la autorización, necesitamos el ClientId y ClientSecret obtenidos en la etapa de registro de la aplicación en foursquare. Dado que estos parámetros no cambian durante la ejecución del programa, los declararemos como constantes.

Cadena final estática privada CLIENT_ID = "FAKE_CLIENT_ID"; Cadena final estática privada CLIENT_SECRET = "FAKE_CLIENT_SECRET";

Final significa que a esta variable se le ha asignado un valor final que no se puede cambiar. Static hace que la variable esté disponible para todas las instancias de la clase dada. Usando el ejemplo de autorización de la biblioteca foursquare-api-java, obtenemos el siguiente código:

Protected void doGet (HttpServletRequest req, HttpServletResponse resp) arroja ServletException, IOException (FoursquareApi foursquareApi = new FoursquareApi (CLIENT_ID, CLIENT_SECRET, CALLBACK_URL); String code = req.getResponseResponse en la página del parámetro. .getAuthenticationUrl ());) else (try (foursquareApi.authenticateCode (código); // Registro exitoso, carga de datos Resultado resultado = foursquareApi.checkinsRecent ("0.0,0.0", 100, 0l); ) captura (FoursquareApiException e) (e.printStackTrace ();)))

Observe que "lanza ServletException, IOException" en la declaración del método. Esta línea significa que el método puede generar potencialmente una de estas excepciones. Una excepción en Java es un objeto que indica cuándo se ha lanzado una excepción. Son verificables y no verificables. Las excepciones marcadas deben manejarse rodeando parte del código con un bloque try-catch, o pasándose por encima. Las excepciones no marcadas generalmente no se manejan porque se lanzan en los casos en que el programa no puede recuperar su estado. En este método, solo manejamos la FoursquareApiException.

Cuando el servidor web recibe una solicitud de una aplicación, utiliza un descriptor de implementación para hacer coincidir la URL de la solicitud con el código que necesita para procesar la solicitud. El descriptor de implementación es un archivo XML llamado web.xml. Agreguemos una descripción del servlet de seguimiento.

pista org.nsa.tracker.TrackerServlet pista / pista

Ahora las solicitudes a / track serán manejadas por nuestro TrackerServlet. Puede establecer el parámetro Callback Url en el valor correcto http: // localhost: 8080 / track.

Para mostrar los resultados, puede utilizar la API de mapas estáticos, proporcionada amablemente por la misma corporación de Google (https://developers.google.com/maps/documentation/staticmaps/). Nuestro servlet generará una página HTML simple y la devolverá en respuesta a una solicitud del usuario.

StringBuilder sb = new StringBuilder (" Rastreador de la NSA"); sb.append (" "); sb.append ("

    "); index = 1; for (Checkin checkin: result.getResult ()) (sb.append (" ") .append (index ++). append (" - ") .append (checkin.getUser (). getFirstName ()) .append (" ") .append (checkin.getUser (). getLastName ()). append ("");) sb.append ("
"); sb.append (" ");

Para generar la página se utiliza la clase StringBuilder, esto se debe a que las cadenas en Java son objetos inmutables. Al concatenar cadenas con el operador +. se crea una nueva línea en la memoria. StringBuilder ahorra memoria mediante el uso de una matriz de caracteres para almacenar cadenas concatenadas. Enviamos la respuesta al usuario:

Byte resultBytes = sb.toString (). GetBytes ("utf-8"); resp.setContentLength (resultBytes.length); resp.getOutputStream (). write (resultBytes);

… Y todo está listo. Lo lanzamos y vemos algo parecido a una imagen con el dicho “El resultado del trabajo del programa”.


¿Que sigue?

La aplicación se puede mejorar, por ejemplo, para separar la recopilación y visualización de datos. Mueva la recopilación de datos a un servicio separado que funcionará constantemente y recordará todos los movimientos de los usuarios en la base de datos. Entonces será posible mostrar no puntos individuales, sino una ruta conectada. Al profundizar un poco en la API de foursquare, puede extraer aún más información sobre la actividad del usuario.

Pero espero haber tenido éxito en lo principal: convencerte de que Java es simple y genial. ¡Nos vemos en un mes!

Programador de Libros para Java

Recomendamos comenzar a aprender el idioma con el libro “Java. Una guía para principiantes de Herbert Schildt. El siguiente nivel es “Java. The Complete Guide "de él, y puede obtener más información sobre los servlets en el libro" Java Servlet and JSP Cookbook "de Bruce W. Perry.

Servlet es un programa java que se ejecuta en el lado del servidor de una aplicación web. Así como los subprogramas amplían dinámicamente la funcionalidad de un navegador web, los servlets amplían dinámicamente la funcionalidad de un servidor web.

Trabaja servlet"pero se puede describir de la siguiente manera: cuando una solicitud proviene de un cliente, el servidor web puede usar un archivo de configuración especial para determinar qué servlet ejecutar. Después de eso, el servidor web inicia la JVM, que a su vez ejecuta el servlet. Servlet procesa la solicitud y transfiere el contenido al servidor web (posiblemente en forma de una página HTML). El servidor web envía una respuesta (una página HTML generada por el servlet) al cliente.

Un servidor WEB es esencialmente una especie de contenedor que carga servlet"s, los ejecuta y, habiendo recibido el resultado de ellos, lo envía al cliente.

Servlet en la arquitectura de aplicaciones web

Por su poder y flexibilidad, servlet"Puede desempeñar un papel importante en la arquitectura del sistema. Pueden realizar tareas de aplicación destinadas al nivel medio, actuar como un servidor proxy para el cliente e incluso mejorar la funcionalidad del nivel medio al agregar soporte para nuevos protocolos y Otras funciones El nivel intermedio actúa como un servidor de aplicaciones en el llamado sistema cliente-servidor de tres niveles y se encuentra entre un cliente "ligero", como un navegador web, y la fuente de datos.

Servlet como servidor proxy

Para admitir subprogramas, los servlets pueden actuar como sus servidores proxy. Esto puede ser importante porque la seguridad de Java solo permite que los subprogramas se conecten al servidor desde el que se descargaron. Si el subprograma necesita conectarse a un servidor de base de datos ubicado en una máquina diferente, servlet puede crear esta conexión para el subprograma.

Temporal y permanente servlet"NS

Los servlets pueden iniciarse y detenerse para cada solicitud del cliente. También pueden comenzar cuando se inicia el servidor web y existir hasta que se detiene. Temporal servlet Los "s se cargan bajo demanda y ofrecen una buena manera de conservar los recursos del servidor para las funciones que se usan con poca frecuencia. Los servlets persistentes se cargan cuando el servidor web se inicia y existen hasta que se apaga. Los servlets se instalan como extensiones persistentes del servidor si el la sobrecarga es muy alta (como establecer una conexión de base de datos) si ofrecen una funcionalidad persistente del lado del servidor (como un servicio RMI), o en los casos en los que necesitan responder a las solicitudes de los clientes lo más rápido posible. servlet"pero permanente o temporal; esta es una función de la configuración del servidor web.

Ciclo de vida del servlet, javax.servlet.Servlet

Los servlets se ejecutan en la plataforma del servidor web como parte del mismo proceso que el propio servidor web. El servidor web es responsable de inicializar, invocar y destruir cada instancia del servlet. El servidor web se comunica con el servlet a través de una interfaz simple: javax.servlet.Servlet.

La interfaz javax.servlet.Servlet incluye tres métodos principales:

  • en eso ()
  • Servicio ()
  • destruir ()

y dos métodos auxiliares:

  • getServletConfig ()
  • getServletInfo ()

Similitudes entre interfaces servlet"Ah, y los subprogramas de Java son obvios. ¡Eso es exactamente para lo que fue diseñado! Los servlets de Java son para los servidores web lo que los subprogramas son para los navegadores web. Un subprograma se ejecuta en un navegador web, ejecutando acciones a petición a través de una interfaz especial. Un servlet hace lo mismo cuando trabaja en un servidor web.

Inicialización de servlet, método init ()

La primera vez que se carga el servlet, se llama al método init (). Esto permite que el servlet realice cualquier trabajo de instalación, como abrir archivos o establecer conexiones con sus servidores. Si el servlet está instalado permanentemente en el servidor, se carga cuando se inicia el servidor. De lo contrario, el servidor invoca el servlet cuando recibe la primera solicitud de un cliente para realizar un servicio proporcionado por ese servlet.

Se garantiza que el método en eso () terminará antes que cualquier otra llamada al servlet, como, por ejemplo, una llamada a un método Servicio ()... tenga en cuenta que en eso () será llamado solo una vez; no se llamará hasta que el servlet se descargue y luego el servidor lo cargue nuevamente.

Método en eso () toma un argumento: una referencia de objeto ServletConfig que contiene argumentos para inicializar el servlet. Este objeto tiene un método getServletContext () devolver un objeto ServletContext que contiene información sobre el entorno del servlet.

Núcleo de servlet, método service ()

Método Servicio () es el corazón del servlet. Cada solicitud del cliente da como resultado una llamada a un método Servicio ()... Este método lee la solicitud y construye un mensaje de respuesta utilizando sus dos argumentos ServletRequest y ServletResponse:

Por tanto, hay dos formas de transferir información del cliente al servlet. El primero es pasar valores en los parámetros de la solicitud. Los valores de los parámetros se pueden insertar en la URL. La segunda forma de transferir información del cliente al servlet es a través de InputStream (o Reader).

Método de trabajo Servicio () esencialmente simple: crea una respuesta a cada solicitud del cliente que se le envía desde el servidor. Sin embargo, tenga en cuenta que pueden procesarse varias solicitudes paralelas al mismo tiempo. Si el método Servicio () requiere cualquier recurso externo, como archivos, bases de datos, es necesario asegurarse de que el acceso a los recursos sea seguro para subprocesos.

Descarga de un servlet, método destroy ()

Método destruir () llamado para liberar todos los recursos (como archivos abiertos y conexiones de bases de datos) antes de descargar el servlet. Este método puede estar vacío si no es necesario realizar ninguna operación de acabado. Antes de llamar al método destruir () el servidor espera que se completen todas las operaciones de servicio o que expire un tiempo específico. Esto significa que el método destruir () se puede llamar mientras se está ejecutando algún método de ejecución prolongada Servicio ().

Es importante formalizar el método destruir () de tal manera que se evite cerrar los recursos requeridos hasta que todas las llamadas Servicio () no terminará.

Configuración de servlet, método getServletConfig ()

Método getServletConfig () devuelve una referencia a un objeto que implementa la interfaz ServletConfig... Este objeto proporciona acceso a la información de configuración del servlet, es decir, acceso a los parámetros de inicialización del servlet y al objeto de contexto del servlet ServletContext que da acceso al servlet y su entorno.

Información de servlet, método getServletInfo ()

Método getServletInfo () lo define el programador que crea el servlet para devolver una cadena que contiene información sobre el servlet, como el autor y la versión del servlet.

Interfaz ServletRequest

ServletRequest proporciona información del cliente sobre los parámetros de solicitud HTTP al servlet, es decir, proporciona datos que incluyen el nombre y los valores de los parámetros, los atributos y un flujo de entrada. Esta información se pasa al método Servicio ().

próximo ejemplo de servlet muestra cómo obtener información de un parámetro solicitud método Servicio ():

Lector BufferedReader; String param1; String param2; servicio público vacío (solicitud ServletRequest, respuesta ServletResponse) (reader = request.getReader (); param1 = request.getParameter ("First"); param2 = request.getParameter ("Second");)

El servlet dispone de información adicional sobre la solicitud a través de métodos, los principales de los cuales se muestran en la siguiente tabla:

getAttribute () Devuelve el valor del atributo especificado de esta solicitud.
getContentLength () Solicite el tamaño, si lo conoce.
getContentType () Devuelve el tipo MIME del cuerpo de la solicitud.
getInputStream () Devuelve un InputStream para leer datos binarios del cuerpo de la solicitud.
GetParameterNames () Devuelve una matriz de cadenas con los nombres de todos los parámetros.
getParameterValues ​​() Devuelve una matriz de valores para el parámetro especificado.
getProtocol () Devuelve el protocolo y la versión de la solicitud como una cadena del formulario /..
getReader () Devuelve un BufferedReader para obtener el texto del cuerpo de la solicitud.
getRealPath () Devuelve la ruta real para la ruta virtual especificada.
getRemoteAddr () La dirección IP del cliente que realiza esta solicitud.
getRemoteHost () El nombre de host de la máquina cliente que realizó esta solicitud.
getScheme () Devuelve el esquema utilizado en la URL para esta solicitud (por ejemplo, https, http, ftp, etc.).
getServerName () El nombre de host del servidor que aceptó la solicitud.
getServerPort () Devuelve el número de puerto utilizado para recibir esta solicitud.

Interfaz ServletResponse

Interfaz ServletResponse es una herramienta para enviar datos a un cliente. Todos los métodos de esta herramienta sirven precisamente para solucionar este problema:

Public java.lang.String getCharacterEncoding () public void setLocale (java.util.Locale loc) public java.util.Locale getLocale ()

El primer método devuelve el tipo de codificación MIME (por ejemplo, UTF8), en el que se mostrará la información. Los dos segundos métodos también funcionan con charset. Indican el idioma utilizado en el documento (por ejemplo, ruso).

Public ServletOutputStream getOutputStream () lanza java.io.IOException

El método getOutputStream devuelve un flujo de salida para el servlet. Esta secuencia se utiliza, por ejemplo, para generar archivos binarios. Los datos de texto se pueden generar usando java.io.Writer:

Public java.io.PrintWriter getWriter () lanza java.io.IOException

El método getWriter () convierte automáticamente las cadenas al juego de caracteres especificado en los métodos getCharacterEncoding () y getLocale ().

Public void setContentLength (int len)

El método setContentLength establece el valor del encabezado HTTP "Content-Length"

Public void setContentType (tipo de cadena)

El método setContentType se utiliza para enviar el tipo de contenido MIME del documento. El campo de encabezado HTTP "Content-Type".

El flujo de salida se almacena en búfer. Esto significa que una parte de los datos se devolverá al cliente solo después de que el búfer esté lleno.

Public void setBufferSize (int size) public int getBufferSize () public void flushBuffer () lanza java.io.IOException public void resetBuffer ()

Los 4 métodos anteriores permiten, respectivamente, establecer el tamaño del búfer de envío, obtener su tamaño, inicializar el envío del contenido del búfer al cliente sin esperar a que se llene y también borrar este búfer de datos.

IsCommitted () booleano público

Con el método isCommitted, puede obtener un indicador de si el envío de datos al cliente ya ha comenzado. La bandera será positiva si ya se ha enviado el encabezado de respuesta HTTP.

Restablecimiento de vacío público ()

Si el encabezado HTTP aún no se ha enviado, el método de restablecimiento "restablece" el encabezado HTTP a sus valores "predeterminados".

Gráficos de JFreeChart en servlets

La biblioteca de gráficos JFreeChart se puede utilizar en servlets para crear gráficos y mostrarlos en las páginas del sitio como imágenes. Se proporcionan detalles y ejemplos del uso de JFreeChart en servlets.

Servlet con la biblioteca de gráficos Chart.js

JNI en servlet

En algunos casos, es posible que deba utilizar JNI en una aplicación WEB. Se proporciona un ejemplo del uso de JNI en servlets.

Mensajes JMS en un servlet

El servlet se puede utilizar para intercambiar JMS mensajes entre aplicaciones. Se proporciona un ejemplo del uso de un servlet para enviar y leer mensajes JMS en un contenedor JBoss.

¿Qué son los servlets? Los servlets son en realidad módulos de procesamiento HTTP y FTP que se utilizan para construir puertas web.

La base de estos portales es el servidor WEB en sí, un programa que mantiene el socket del servidor, recibe y transmite datos. La mayoría de las veces, para acelerar el trabajo, el servidor no está escrito en Java, sino en algún otro lenguaje de programación (por ejemplo, en C ++).

Un servlet básico funciona junto con el servidor. Es a él a quien el servidor envía datos y de él recibe la respuesta enviada al cliente. De hecho, el servlet subyacente es el "cerebro" del servidor. La función principal de este servlet es leer la solicitud del cliente, descifrarla y, de acuerdo con el descifrado, transferir el trabajo al servlet responsable de este tipo de información solicitada. A menudo, el propio servidor actúa como servlet subyacente para lograr la velocidad. Así es exactamente como funciona Jacarta Tomcat.

La figura muestra un diagrama de la transferencia de llamadas (solicitudes) y respuestas (respuestas) entre el servidor y los servlets. Este diagrama muestra el funcionamiento de un servidor HTTP que tiene varias páginas JSP y dos recursos "/ sample1" y "/ sample2", que son procesados ​​por dos servlets: "Sample1 Servlet" y "Sample2 Servlet", respectivamente.

Analicemos paso a paso lo que se muestra en la figura:

  1. el cliente se conecta al servidor
  2. el servidor pasa la solicitud al "Servlet básico"
  3. el servlet subyacente extrae el URI del recurso de la solicitud
    • si el URI apunta a "/ sample1", la solicitud totalmente(sin cambios) pasado al servlet "Sample1 Servlet", que procesa aún más esta solicitud
    • si el URI apunta a "/ sample2", el servidor pasa la solicitud al "Sample2 Servlet"
    • en todos los demás casos, la solicitud se pasa al módulo "JSP Servlet"
  4. el servlet que recibió el control procesa los datos, crea una respuesta y luego la respuesta se envía de vuelta al servlet subyacente.
  5. el servlet básico, sin procesar los datos recibidos, los envía inmediatamente al servidor
  6. el servidor emite datos al cliente

Así, la tarea de procesar una solicitud se divide en partes lógicas, de cada una de las cuales es responsable un módulo separado, su propio "bloque de software". De hecho, puede haber muchos más pasos para procesar una solicitud. Por ejemplo, diferentes módulos pueden ser responsables de los métodos "GET" y "POST".

Interfaz de servlet

Lo que todos estos módulos tienen en común es que están interconectados de un extremo a otro mediante la interfaz javax.servlet.Servlet

Echemos un vistazo a esta interfaz. Enumera solo 5 métodos:

Public void init (ServletConfig config) lanza ServletException Este método se llama para informar al servlet que está incluido como un módulo para atender las solicitudes de los clientes. El parámetro de configuración separa la interfaz javax.servlet.ServletConfig, que transporta información sobre el entorno del servidor, el nombre del servlet, los parámetros iniciales y otras ventajas. La interfaz javax.servlet.ServletConfig se discutirá un poco más adelante. Se supone que después de llamar a esta función, el servlet guardará ordenadamente esta configuración en su variable y la emitirá usando otro método: public ServletConfig getServletConfig () Después de recibir información del sistema usando "getServletConfig ()", el servidor puede querer averiguar el nombre del autor, la fecha de creación, otra información sobre el servlet, que se logra llamando a public String getServletInfo ()

Para procesar la solicitud y obtener el resultado de su procesamiento, use la función

El servicio de vacío público (solicitud ServletRequest, respuesta ServletResponse) arroja ServletException, java.io.IOException En esta función, se pasan dos herramientas al código que procesará los datos: una para recibir datos del servidor, la otra para enviar el resultado de el servlet. En consecuencia, estos son los parámetros de solicitud y respuesta que separan las interfaces javax.servlet.ServletRequest y javax.servlet.ServletResponse. Todo el trabajo con datos se realiza precisamente a través de estas interfaces, por lo que hablaremos de ellas con más detalle a continuación.

Una vez que el servidor ya no necesita este módulo, se llama al método

Public void destroy () que completa todas las operaciones con el objeto servlet.

Interfaz ServletConfig

Los 4 métodos autoexplicativos componen la interfaz javax.servlet.ServletConfig:

Public String getServletName () public ServletContext getServletContext () public String getInitParameter (String name) public java.util.Enumeration getInitParameterNames ()

Creo que el propósito de todas las funciones es claro, excepto

Public ServletContext getServletContext () Este método devuelve un enlace a una herramienta de servidor muy útil:

Interfaz ServletContext

ServletContext es una interfaz que define el acceso a las siguientes funciones muy útiles:

Objeto público getAttribute (nombre de cadena) public java.util.Enumeration getAttributeNames () public void setAttribute (nombre de cadena, objeto de objeto) public void removeAttribute (nombre de cadena) Cuatro métodos para trabajar con atributos. El papel de los atributos lo desempeña cualquier objeto de cualquier clase. El propósito de estas funciones es transferir diferentes objetos entre servlets no relacionados. public String getInitParameter (String name) public java.util.Enumeration getInitParameterNames () Acceso a los parámetros con los que se inició el servidor. También puede haber un nombre de host, un puerto y otras cosas útiles. public int getMajorVersion () public int getMinorVersion () Devuelve las versiones de la API de servlet. public String getMimeType (archivo de cadena) Devuelve el tipo MIME asociado con el archivo especificado en la variable de archivo. ¡Recuerde cómo tuvo que definir MIME en SimpleWEBServer y aprecia la conveniencia! public java.util.Set getResourcePaths () public java.net.URL getResource (ruta de cadena) lanza java.net.MalformedURLException public InputStream getResourceAsStream (ruta de cadena) Devuelve rutas a los recursos disponibles para el servidor y los recursos mismos como URL y transmite datos . public RequestDispatcher getRequestDispatcher (ruta) public RequestDispatcher getNamedDispatcher (nombre) RequestDispatcher es una herramienta para reenviar una solicitud a otro recurso. Estas funciones son necesarias para obtener el objeto de esta herramienta para los recursos especificados. Es decir, para enviar una solicitud al servlet "sample1" desde el cuerpo del servlet, puede hacer esto: getServletConfig (). GetServletContext (). GetNamedDispatcher ("sample1"). Forward (solicitud, respuesta);

La propia clase RequestDispatcher incluye solo dos métodos:

Public void forward (solicitud ServletRequest, respuesta ServletResponse) arroja ServletException, java.io.IOException public void include (solicitud ServletRequest, respuesta ServletResponse) arroja ServletException, java.io.IOException El primero es redirigir la solicitud y el segundo es incluir el resultado del servlet llamado al resultado del actual. Por ejemplo, el servlet 1 imprime la palabra "prueba 1", luego llama a include para el servlet dos y luego imprime la palabra "prueba 2". Servlet 2 simplemente imprime la palabra "y". El servlet 1 generará la cadena "prueba 1 y prueba 2". public void log (String msg) Escribe algo en el registro del servidor. public void log (mensaje de cadena, Throwable throwable) Defina una excepción y una frase que se registrará cuando se reciba esta excepción. public String getRealPath (String path) Traduce una ruta como "/index.html" a "http: //host/contextPath/index.html" public String getServerInfo () Devuelve el nombre del servidor. public ServletContext getContext (String uripath) Este método le permite intercambiar ServletContext entre diferentes recursos del mismo servidor. public String getServletContextName () Devuelve el nombre del servlet al que pertenece este objeto de interfaz ServletContect.

Interfaz ServletRequest

La interfaz ServletRequest es una herramienta para obtener parámetros de solicitud HTTP. Esta interfaz tiene varios métodos que son idénticos en nombre y propósito al ServletContext:

Public Object getAttribute (Nombre de cadena) public java.util.Enumeration getAttributeNames () public void setAttribute (Nombre de cadena, Objeto o) public void removeAttribute (java.lang.String nombre) public String getServerName () public RequestDispatcher getRequestDispatcher (Ruta de cadena)

Los métodos restantes le permiten trabajar cómodamente con el encabezado de solicitud HTTP:

Public String getCharacterEncoding () public void setCharacterEncoding (String env) lanza java.io.UnsupportedEncodingException Trabajar con codificación de caracteres en campos de encabezado HTTP. Las funciones establecen el método para descifrar las solicitudes CGI del formulario% NN en caracteres ordinarios. Por ejemplo, qué estándar (KOI8-R, windows-1251 o UTF-8) se debe utilizar para descifrar caracteres cirílicos. public int getContentLength () public String getContentType () Lee los campos "Content-Length", "Content-Type" de la solicitud HTTP. public jString getParameter (String name) public java.util.Enumeration getParameterNames () public String getParameterValues ​​(String name) public java.util.Map getParameterMap () Funciones para obtener un campo del encabezado HTTP y su valor. public ServletInputStream getInputStream () lanza java.io.IOException public java.io.BufferedReader getReader () lanza java.io.IOException Obtiene el flujo de datos entrante o su "lector". El lector se utiliza para leer información de texto: descifrará automáticamente las cadenas de acuerdo con el juego de caracteres especificado. ¡Atención! Hay un error significativo en J2EE 1.3: al descifrar el carácter% 25 (el carácter% en las solicitudes Publicar y Obtener), Reader da un error (el error se ve en los servidores Tomcat 4 y Resign). Es posible que exista un error similar con otros símbolos. public String getProtocol () Obtiene la versión HTTP del protocolo de solicitud (por ejemplo, "HTTP / 1.1"). public String getScheme () Devuelve el nombre del esquema de solicitud. Por ejemplo, "http", "https" o "ftp". public int getServerPort () public String getRemoteAddr () public String getRemoteHost () public boolean isSecure () Puerto del servidor, IP del cliente, nombre de host del cliente y si la conexión es privada (HTTPS) public java.util.Locale getLocale () public java.util .Enumeration getLocales () El idioma de documento preferido del cliente (el resultado de procesar el campo "Accept-Language")

Interfaz ServletResponse

La interfaz ServletResponse es una herramienta para enviar datos al cliente. Todos los métodos de esta herramienta sirven exactamente para este propósito:

Public java.lang.String getCharacterEncoding () public void setLocale (java.util.Locale loc) public java.util.Locale getLocale () El primer método devuelve el tipo de codificación MIME (por ejemplo, UTF8), en el que se incluirá la información desplegado. Los dos segundos métodos también funcionan con charset. Indican el idioma utilizado en el documento (por ejemplo, ruso). public ServletOutputStream getOutputStream () lanza java.io.IOException Devuelve el flujo de salida para el servlet. Esta secuencia se utiliza, por ejemplo, para generar archivos binarios. Los datos de texto se pueden generar utilizando java.io.Writer: public java.io.PrintWriter getWriter () lanza java.io.IOException Este método convierte automáticamente las cadenas al juego de caracteres especificado en los métodos getCharacterEncoding () y getLocale (). public void setContentLength (int len) Este método establece el valor del campo de encabezado HTTP "Content-Length" public void setContentType (tipo de cadena) Método para enviar el tipo de contenido MIME del documento. El campo de encabezado HTTP "Content-Type". public void setBufferSize (int size) public int getBufferSize () public void flushBuffer () lanza java.io.IOException public void resetBuffer () El punto es que el flujo de datos de salida está almacenado en búfer. Esto significa que el siguiente fragmento de datos se enviará al cliente solo después de que el búfer esté lleno. Estos métodos permiten, respectivamente, establecer el tamaño del búfer de envío, obtener su tamaño, inicializar el envío del contenido del búfer al cliente, sin esperar a que se llene, así como borrar este búfer de datos. public boolean isCommitted () Con este método, puede obtener un indicador de si los datos ya se han enviado al cliente. La bandera será positiva si ya se ha enviado el encabezado de respuesta HTTP. public void reset () Si el encabezado HTTP aún no se ha enviado, este método "restablece" el encabezado HTTP a sus valores "predeterminados".

Tipos de servlet predefinidos

La API de Java Servlet, además de las interfaces reales, también contiene varias clases de servlet que pueden servir como base para sus programas.

La base para todas estas clases es la clase abstracta javax.servlet.GenericServlet:

La clase pública abstracta GenericServlet implementa Servlet, ServletConfig, java.io.Serializable

Como puede ver en la definición de esta clase, tiene todos los métodos de las interfaces Servlet y ServletConfig. El único método no implementado es

El servicio público vacío abstracto (ServletRequest req, ServletResponse res) arroja ServletException, java.io.IOException que se declaró abstracto.

Sobre la base de esta clase, se creó otra clase abstracta: javax.servlet.http.HttpServlet:

La clase pública abstracta HttpServlet extiende GenericServlet implementa java.io.Serializable

Esta clase fue creada de acuerdo con el concepto de "aún más conveniencia para el programador" y tiene muchos métodos útiles:

Protected void doDelete (HttpServletRequest req, HttpServletResponse resp) arroja ServletException, java.io.IOException protected void doGet (HttpServletRequest req, HttpServletResponse resp) lanza Servlet. ThrowException, javaidio req. HttpServletResponse resp) lanza ServletException, java.io.IOException protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws Servlet.Exception lanza ServletException, java.io.IOException protected void doTracettReq. IOException protected void service (HttpServletRequest req, HttpServ throws, java. Resp., ServletR esponse res) lanza ServletException, java.io.IOException Diferentes opciones de servicio (ServletRequest req, ServletResponse res) para diferentes métodos HTTP desde DELETE y GET hasta PUT y TRACE. Y para recibir datos cómodamente a través de la interfaz CGI sin descifrar el encabezado, se crearon las clases HttpServletRequest y HttpServletResponse, que se incluyen con HttpServlet en el paquete javax.servlet. de la última modificación del objeto HttpServlet req Toma el valor de hora del campo "Fecha" del encabezado de la solicitud HTTP. Si no se encuentra el campo, devuelve -1.

En consecuencia, analizaremos las interfaces HttpServletRequest y HttpServletResponse. Heredan de ServletRequest y ServletResponse, respectivamente.

HttpServletRequest, además de los métodos heredados de ServletRequest, también tiene los siguientes métodos muy útiles:

Cookie getCookies () Devuelve el conjunto de cookies enviadas por el cliente al servidor.

La clase Cookie, que forma parte del mismo paquete javax.servlet.http, contiene toda la información posible sobre una cookie. Los métodos más importantes de esta clase son

Int getMaxAge () String getName () String getValue () dando, respectivamente, cuánto tiempo de vida le queda a esta cookie, el nombre de la cookie y su valor. También Cookie (String name, String value) void setValue (String newValue) void setMaxAge (int expiry) para crear una cookie, establecer su valor y edad máxima. long getDateHeader (String name) Devuelve la fecha del encabezado HTTP, si lo hubiera. int getIntHeader (java.lang.String name) Devuelve el valor numérico del campo denominado nombre del encabezado de la solicitud HTTP String getMethod () Devuelve el método de solicitud HTTP. String getQueryString () String getRequestURI () StringBuffer getRequestURL () Devuelve la cadena contenida en la URL del documento después del carácter "?", El URI del documento y la URL completa. HttpSession getSession () HttpSession getSession (boolean create) boolean isRequestedSessionIdFromCookie () boolean isRequestedSessionIdFromURL () boolean isRequestedSessionIdValid () Funciones. permitiéndole trabajar con un mecanismo de transferencia de datos tan importante como las sesiones.

Las sesiones son necesarias para arrastrar datos de una página a otra después del usuario. Por ejemplo, un usuario visita la página (1), donde se le envían algunos datos para la página (2), y ese otro guarda otras cosas para la página (3).

En principio, en la página (1) puedes enviar datos al usuario, luego obtenerlos en la página (2), agregar algo, enviarlo al usuario ... De esta manera, tendrás que enviar constantemente todo el conjunto de datos. del cliente al servidor y viceversa, y muchas veces. Además del hecho de que dicho reenvío no siempre es conveniente, también consume tráfico.

Puede hacer lo mismo de manera diferente: use el mecanismo de sesión. Este mecanismo funciona de la siguiente manera: el servidor guarda los datos enviados por el usuario en un archivo separado: el archivo de sesión. Todo el trabajo para cambiar los datos se hará con el contenido de este archivo. El cliente recibe una "clave de sesión" (también conocida como clave de sesión, también conocida como ID de sesión), un puntero único a un archivo que contiene datos específicamente para este usuario. Ahora, para recibir todos los datos relacionados con este cliente, el servidor solo necesita conocer la clave de sesión. La ventaja de este método es la conveniencia y rapidez de su uso.

Estos son todos los métodos principales de la interfaz HttpServletRequest. Para obtener una lista completa de métodos, consulte la documentación de la API de Java Servlet.

Ahora sobre la interfaz HttpServletRequest. La principal diferencia entre las clases que comparten esta interfaz es que los datos no se emiten inmediatamente. Primero, todos los datos se agrupan en una respuesta HTTP. La respuesta solo se envía después de que HttpServlet.service () haya terminado de ejecutarse.

Y entonces, sobre los métodos:

Void addHeader (nombre de cadena, valor de cadena) void addIntHeader (nombre de cadena, valor int) void addDateHeader (nombre de cadena, fecha larga) Los métodos agregan parámetros al encabezado HTTP. El último método establece el parámetro "Fecha". void addCookie (Cookie cookie) El método agrega una cookie al encabezado booleano containsHeader (Nombre de cadena) Le permite averiguar si el encabezado ya contiene el parámetro especificado. String encodeURL (String url) String encodeRedirectURL (String url) El primer método codifica caracteres utilizando el reemplazo% NN. El segundo método hace lo mismo y llama a void sendRedirect (String location) void setStatus (int sc) void sendError (int sc) void sendError (int sc, String msg) El primero establece el código de retorno, los dos segundos envían un mensaje de error . La interfaz tiene los siguientes errores posibles para el parámetro sc, correspondientes a los códigos de retorno del protocolo HTTP: SC_CONTINUE - Código de estado (100) SC_SWITCHING_PROTOCOLS - Código de estado (101) SC_OK - Código de estado (200) SC_CREATED - Código de estado (201) SC_ACCEPTED - Código de estado (202) SC_NON_AUTHORITATIVE_INFORMATION - Código de estado (203) SC_NO_CONTENT - Código de estado (204) SC_RESET_CONTENT - Código de estado (205) SC_PARTIAL_CONTENT - Código de estado (206) SC_MULTIPLE_CHOICES (Estado_MULTIPLE_CHOICES_Código) Código de estado SC2 - Código de estado (300) 303) SC_NOT_MODIFIED - Código de estado (304) SC_USE_PROXY - Código de estado (305) SC_BAD_REQUEST - Código de estado (400) SC_UNAUTHORIZED - Código de estado (401) SC_PAYMENT_REQUIRED - Código de estado (402) SC_FORBID (Código de estado) - Código de estado (404) SC_FORBID (Código de estado) - Código de estado (404) Código de estado (405) SC_NOT_ACCEPTABLE - Código de estado (406) SC_PROXY_AUTHENTICATION_REQUIRED - Código de estado (407) SC_REQUEST_TIMEOUT - Estado s código (408) SC_CONFLICT - Código de estado (409) SC_GONE - Código de estado (410) SC_LENGTH_REQUIRED - Código de estado (411) SC_PRECONDITION_FAILED - Código de estado (412) SC_REQUEST_ENTITY_TOO_LARGE - Estado (413) Código de SCABLE_REQUEST_FREQUEST (4QUOTED15) ) SC_EXPECTATION_FAILED - Código de estado (417) SC_INTERNAL_SERVER_ERROR - Código de estado (500) SC_NOT_IMPLEMENTED - Código de estado SC_BAD_CodeAEW2) (504) SC_HTTP_VERSION_NOT_SUPPORTED - Código de estado (505)

Eso es todo lo que hay que decir sobre HttpServletResponse

Uso de servlets en aplicaciones WEB

Ahora hablemos sobre el uso de servlets en aplicaciones WEB. Para hacer esto, daré dos ejemplos útiles que pueden ser útiles en la práctica.

El primer ejemplo muestra métodos para trabajar con un HttpServlet y generar contenido de página HTML comprimido. En teoría, la página HTML en la respuesta del navegador se muestra en texto sin formato, pero para reducir la cantidad de datos enviados, puede utilizar la compresión GZIP. Los navegadores modernos (al menos los navegadores de cuarta generación y superiores) admiten este método de envío de información textual y mostrarán la página como si no se hubiera comprimido.

importar java. io. *; importar javax. servlet. *; importar javax. servlet. http. *; importar java. util. Código Postal. *; // servlet hereda de HttpServlet ZipServlet de clase pública extiende HttpServlet ( // función para manejar el método GET public void doGet (solicitud HttpServletRequest, respuesta HttpServletResponse) lanza ServletException, IOException ( // configura la página para que sea un documento HTML respuesta. setContentType ("texto / html"); // tomar el parámetro "Accept-Encoding" del encabezado HTTP Codificaciones de cadena = solicitud. getHeader ("Aceptar codificación"); // tomar el parámetro "codificación" - la codificación especificada previamente del documento String encodeFlag = solicitud. getParameter ("codificación"); // Dónde saldremos PrintWriter out; // si el campo "Accept-Encoding" está presente en la solicitud if (codificaciones! = nulo) ( // y si este campo contiene el valor "gzip" y la codificación aún no se ha establecido, if ((codificaciones. indexOf ("gzip")! = - 1) &&! encodeFlag. equals ("none")) ( // luego la salida será seguida por uno y comprimirá el texto usando GZIP out = new PrintWriter (nuevo GZIPOutputStream (respuesta. getOutputStream ()), falso); // y establezca una bandera para el navegador de que el documento se comprimirá respuesta. setHeader ("Codificación de contenido", "gzip"); ) else out = respuesta. getWriter (); ) demás // de lo contrario, saldremos sin compresión out = respuesta. getWriter (); fuera. println ("¡¡¡Esto es una prueba !!!"); // escribe el cuerpo del documento fuera. cerrar (); // y cierra la salida. // Todo, una vez completada esta función, se enviará el documento } }

El segundo ejemplo muestra cómo un servlet puede representar una página de forma continua. Este tipo de visualización de página se puede utilizar, por ejemplo, en chats: para leer mensajes nuevos, no necesitará actualizar la página cada vez, los mensajes nuevos simplemente se descargarán con el tiempo. Cabe señalar que algunos servidores proxy no admiten este tipo de transferencia de datos, pero con esto, por desgracia, no se puede hacer nada.

importar java. io. *; importar javax. servlet. *; // el programa implementa la interfaz Servlet class DoloadServlet implementa Servlet (ServletConfig config; // ServletConfig objeto public DoloadServlet () () // haciendo nada // guardar la configuración durante la inicialización public void init (ServletConfig config) lanza ServletException (this. config = config;) // da la configuración guardada public ServletConfig getServletConfig () (return config;) // información del servlet public String getServletInfo () (return "DoloadServlet";) public void destroy () () // haciendo nada // Solicitud de procesamiento public void service (solicitud ServletRequest, respuesta ServletResponse) lanza ServletException, java. io. IOException ( // no analizaremos la solicitud, es un desastre // crea un encabezado HTTP: String head = "HTTP / 1.0 200 OK \ n" + + "Servidor: DoloadServlet \ n" + "Tipo de contenido: texto / html; juego de caracteres = UTF-8 \ n"+ "Conexión: Keep-Alive \ n" + "Codificación de contenido: multiparte / mixto \ n"+ "Codificación de transferencia: fragmentada" + "Pragma: sin caché \ n \ n"; // ahora agregue los datos iniciales // para este ejemplo, 20 etiquetas "
"con salto de línea
para (int i = 0; i< 20 ; i++ ) head = head + "
\ n "; // tomar el flujo de salida ServletOutputStream os = respuesta. getOutputStream (); // escribe el título y los datos iniciales allí os. imprimir (cabeza); // envía todo lo escrito en el búfer al cliente respuesta. flushBuffer (); // comienza a agregar nuevas líneas: // estas líneas se verán así: número de línea, luego "
\ n "
// cada nueva línea aparecerá cada 3 segundos int i = 0; mientras (verdadero) ( // contador de incrementos i ++; // escribe la línea os. imprimir ("" + i + "
\ n "); // vaciar la respuesta del búfer.flushBuffer (); // congelar la transmisión durante 3 segundos intentar (dormir (3000);) atrapar (Excepción e) ())))

Queda por decir que el mecanismo del servlet es muy flexible y le permite hacer cosas que podrían requerir escribir un servidor WEB separado (como, por ejemplo, en el caso de un servlet de reanudación). Las desventajas de los servlets son la baja velocidad del primer lanzamiento (el servlet simplemente lo compila la máquina JIT), el alto consumo de memoria y la falta de todos los programas Java: la baja velocidad de trabajo con cadenas. La última circunstancia se hace evidente cuando funcionan los servlets que aceptan datos de texto en solicitudes POST. Una solicitud POST de 50 KB a un HttpServlet cuando se analiza con HttpServletRequest.getReader () puede paralizar el servidor durante un par de minutos. Lo mismo se aplica a otros programas Java.

Aquí hay dos pequeños ejemplos:

// dado una cadena String text // ejemplo 1 // trabajar con una cadena usando la operación "+" para String String test1 = ""; para (int i = 0; i< text. length(); i++ ) test1 += text. charAt(i); // ejemplo 2 // trabajar con una cadena usando un búfer char buf = nuevo char [text. largo ()]; para (int i = 0; i< text. length(); i++ ) buf[ i] = text. charAt(i); String sample2 = new String(buf);

Si tomamos cadenas pequeñas, de hasta 2-3 kb, entonces las diferencias en el trabajo de los ejemplos son insignificantes, pero si tomamos una cadena de texto con un tamaño de al menos 10 kb, entonces, en el primer caso, el programa funcionará. con la cuerda mucho más lenta. Esto es por diseño en Java y es un problema en la implementación de las funciones de la clase String. Entonces, si desea escribir un servlet rápido, evite trabajar con cadenas largas a través de la clase String, por ejemplo, use la clase StringBuffer. Esta advertencia se aplica principalmente a la recepción de textos grandes de la red y al procesamiento de archivos locales (por ejemplo, en el caso de una base de datos de texto para un libro de visitas con una gran cantidad de mensajes).

Otro problema se refiere a la multitarea del sistema WEB. Tenga en cuenta que varios usuarios pueden solicitar su servlet al mismo tiempo. A menudo existen problemas con la sincronización de datos, el intercambio de información entre diferentes subprocesos computacionales del mismo servlet, y el problema más común es el problema del acceso sincrónico a archivos y otros recursos del sistema con nombre. Por ejemplo, un programa ha abierto un archivo para leerlo, mientras que el otro intenta escribir algo allí. Como resultado, el segundo programa obtiene una excepción o espera a que se libere el archivo para su escritura. En este sentido, me gustaría llamar su atención: no deje los arroyos sin cerrar detrás de usted y cierre los arroyos tan pronto como ya no los necesite. La secuencia, por supuesto, se cerrará automáticamente más tarde, pero esto solo sucederá cuando el "limpiador" llegue a ella y, mientras tanto, el segundo programa aún no tendrá acceso de escritura al archivo.

Además de la multitarea, me gustaría señalar que utilizando los métodos "Object getAttribute (String name)" y "void setAttribute (String name, Object object)" de la interfaz ServletContext, puede intercambiar datos entre servlets, incluida la sincronización de datos.

Una de las características más agradables de Java es su naturaleza multifacética. Por supuesto, la creación de aplicaciones tradicionales de escritorio e incluso móviles es excelente. Pero, ¿qué pasa si desea salirse de los caminos trillados y entrar en el territorio del desarrollo de aplicaciones web en Java? La buena noticia para usted es que el lenguaje viene con una API de Servlet completa que le permite crear aplicaciones web robustas sin muchos problemas.

Escribir aplicaciones Java con servlets

Entonces, ya hemos creado los archivos de configuración para la aplicación. Sin embargo, en su estado actual, literalmente no hace nada. Queremos que los clientes puedan registrarse utilizando un formulario HTML, por lo que lo siguiente que debemos hacer es crear archivos JSP que mostrarán el formulario anterior y los detalles del cliente después de que el registro sea exitoso. Eso es lo que vamos a hacer ahora.

Estamos trabajando en la apariencia

La apariencia de la aplicación estará determinada por dos archivos JSP; en el contexto de MVC, se denominan vistas. El primero se encargará de visualizar el formulario de registro y los posibles errores que se produzcan tras comprobar los datos introducidos. La segunda será una página de bienvenida regular, que mostrará los datos ingresados ​​por el cliente una vez completado con éxito el proceso de registro.

Aquí está el primer archivo JSP:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> registro

registro

$ (violación).