1.1 servlet de interfaz
Hoy comenzamos un tema nuevo e interesante: los servlets . Fue la adición de servlets a Java lo que llevó a Java a ser el estándar de facto para aplicaciones de servidores grandes. El 80% de todo el software empresarial del mundo está escrito en Java. Y en China, todo es al 100%. Entonces, ¿qué son los servlets?
Un servlet es exactamente lo que convierte un programa Java en un servicio web y le permite procesar las solicitudes de los clientes. Y fue así...
En los años 90, inmediatamente después de la llegada de la World Wide Web, aparecieron los clientes web (navegadores) y los servidores web. Los servidores web generalmente simplemente distribuyen el archivo que tenían almacenado a través de Internet: páginas html, scripts, imágenes, etc.
En algún momento, todos llegaron a la conclusión de que sería necesario hacer que ambos lados fueran más inteligentes. Se agregó JavaScript a las páginas HTML y se agregaron complementos a los servidores: scripts especiales que se llamaron en respuesta a ciertas solicitudes e hicieron que el comportamiento del servidor fuera más flexible e inteligente.
Entonces, un servlet es un complemento de Java que se incorporó Java web-server
y le permitió ejecutar código Java cuando se solicitó para ciertas páginas. Y ya este código Java, representado por una clase heredada de la clase Servlet, hizo lo que pretendían sus desarrolladores.
Y como ya sabrás, el servidor web Java más popular es Tomcat . Nombrado, por cierto, en honor al gato Tom de la caricatura "Tom y Jerry".
¿Cómo interactúa Tomcat con los servlets? De hecho, este proceso está estandarizado y se denomina ciclo de vida del servlet . En él, un servlet es un objeto cargable y un servidor web es un contenedor de servlet .
Si el servlet aún no se ha cargado , entonces:
- El contenedor carga la clase de servlet.
- El contenedor crea una instancia de la clase (objeto) del servlet.
- El contenedor llama a un método
init()
en el objeto servlet. El método se llama una sola vez.
Ciclo de trabajo estándar: atender una solicitud de cliente :
- Cada solicitud se procesa en un hilo separado.
- El contenedor llama a un método
service()
en el servlet y pasa allí los objetos ServletRequest y ServletResponse. - Para terminar el servlet, se llama a un método
destroy()
en el objeto del servlet. Se llama una sola vez.
Puede haber muchas razones por las que un servlet termina:
- El programador reinicia el servidor web, es necesario cerrar correctamente todos los servlets.
- El programador carga una nueva versión del servlet, la anterior debe descargarse correctamente.
- Etcétera.
Recuerda lo principal: el servidor web y sus servlets deberían funcionar sin fallas y reiniciarse durante meses, atendiendo miles de solicitudes por minuto. Por lo tanto, el código para cargar, trabajar y descargar un servlet siempre debe escribirse con una calidad muy alta.
1.2 Clase HttpServlet
La clase Servlet existe para estandarizar cómo funcionan un servlet y un contenedor. Los programadores no trabajan directamente con esta clase. Bueno, rara vez funcionan. La clase más utilizada HttpServlet
se hereda de Servlet.
Esta clase tiene varios métodos que nos serán de utilidad. A menudo los usará:
Método | Descripción | |
---|---|---|
1 | init() |
Llamado una vez cuando se carga el servlet |
2 | destroy() |
Llamado una vez cuando se descarga el servlet |
3 | service(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud al servlet |
4 | doGet(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud GET al servlet |
5 | doPost(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud POST al servlet |
6 | doHead(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud HEAD al servlet |
7 | doDelete(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud DELETE al servlet |
8 | doPut(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud PUT al servlet |
Los métodos init()
y destroy()
se heredan de la clase Servlet. Por lo tanto, si decide anularlos en su servlet, también deberá llamar a su implementación desde la clase base. El comando se utiliza para esto super.method name()
.
Ejemplo de servlet:
public class FirstHttpServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Getting the parameter “secret” from request
String secret = request.getParameter("secret");
// Put parameter “secret” into Http-session
HttpSession session = request.getSession(true);
session.setAttribute("secret", secret);
// Print HTML as response for browser
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Header</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet example "+ secret +"</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
1.3 método de servicio (HttpServletRequest, HttpServletResponse)
Si observa el procesamiento de una solicitud de cliente desde el punto de vista de un servlet, entonces las cosas son más o menos así.
Para cada solicitud del cliente, el contenedor (servidor web) crea HttpServletRequest
objetos HttpServletResponse
y luego llama a un método service(HttpServletRequest request, HttpServletResponse response)
en el servlet correspondiente. Estos objetos se le pasan para que el método pueda tomar los datos necesarios request
y poner el resultado del trabajo en response
.
El método service()
tiene una implementación predeterminada. Si no se redefine, se ejecutará. Eso es lo que hace.
El método service()
determina el tipo de método HTTP a partir de la solicitud (GET, POST, ...) y llama al método correspondiente a la solicitud.
Método | Descripción | |
---|---|---|
1 | service(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud al servlet |
2 | doGet(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud GET al servlet |
3 | doPost(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud POST al servlet |
4 | doHead(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud HEAD al servlet |
5 | doDelete(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud DELETE al servlet |
6 | doPut(HttpRequest, HttpResponse) |
Llamado para cada nueva solicitud PUT al servlet |
En su clase, puede redefinir un método service()
o dejarlo solo, pero luego redefinir los métodos doGet()
, doPost()
, ... según sea necesario.