Servlet

Servlet jest podstawowym elementem aplikacji biznesowych tworzonych w języku Java. W rzeczywistości jest to klasa rozszerzająca klasę HttpServlet, która jest zdolna do przetwarzania żądań HTTP. Serwlety wykorzystywane są zarówno w aplikacjach Javy EE jak i tych tworzonych w Spring MVC.

Serwlety do poprawnego działania wymagają kontenera serwletów, wśród których najpopularniejsze to Tomcat, czy Jetty.

Mapowanie adresu URL

W obecnej specyfikacji Javy EE, Servlety dostępne są w wersji 3.1, a od Javy EE 8 pojawi się ich wersja 4.0. Największą zmianę przyniosły Servlety 3.0, w których wprowadzono możliwość określenia docelowego adresu URL nie tylko poprzez plik web.xml (deskryptor wdrożenia), ale również w sposób deklaratywny poprzez adnotację**@WebServlet**.

W starszych wersjach serwletów mapowanie ustawialiśmy w pliku web.xml w następujący sposób:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">
	
	<servlet>
		<servlet-name>Hello</servlet-name>
		<servlet-class>pl.javastart.servlet.HelloServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Hello</servlet-name>
		<url-pattern>/hi</url-pattern>
	</servlet-mapping>
</web-app>

Dwie kluczowe sekcje to <servlet> , która zawiera definicję servletu oraz <servlet-mapping> zawierająca mapowanie adresu URL. Jeśli więc wyślemy żądanie do naszej aplikacji pod adres /hi , to wywołana zostanie jedna z metod klasy HelloServlet. Dostępne metody to:

  • doGet()
  • doPost()
  • doTrace()
  • toHead()
  • doPut()
  • doOptions()

jak nazwy sugerują odpowiadają one poszczególnym metodom HTTP, czyli GET, POST, TRACE...

Od specyfikacji Servlet 3.0 plik web.xml stał się opcjonalny ze względu na silny zwrot w kierunku konfiguracji opartych o adnotacje i automatyczne konfiguracje. Od Javy EE6 (servlet 3.0) najczęściej spotkamy się więc z mapowaniem postaci:

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

@WebServlet("/hi")
public class HelloServlet extends HttpServlet {
	//...
}

Cykl życia

Cykl życia Servletu wygląda tak, że przy pierwszym odwołaniu do niego kontener (np. Tomcat) tworzy obiekt klasy reprezentującej serwlet zmapowany na dany adres URL. Zycie obiektu składa się z kilku etapów:

  • utworzenie obiektu serwletu poprzez konstruktor
  • wywołanie metody init()
  • wielokrotne wywoływanie metod doGet, doPost itp.
  • wywołanie metody destroy()

Ważne jest to, że powstanie tylko jeden taki obiekt i będzie współdzielony pomiędzy wszystkich użytkowników naszej aplikacji, dlatego należy zwrócić szczególną uwagę na kwestie wielowątkowości - np. definiowanie w serwletach współdzielonych, niesynchronizowanych pól klasy.

Kurs Java EE i Jakarta EE

Żądanie i odpowiedź

Każda z metod wspomnianych w punkcie Mapowane adresu URL przyjmuje dwa parametry:

  • HttpServletRequest
  • HttpServletResponse

które reprezentują odpowiednio żądanie i odpowiedź HTTP. Z punktu widzenia programisty z pierwszego obiektu możemy odczytać parametry żądania, ciasteczka, czy też odwołać się do sesji powiązanej z użytkownikiem, natomiast korzystając z obiektu response możemy wysłać odpowiedź.

serlvlet request lifecycle

Servlet a JSP

Servlety mają silny związek z technologią JSP (JavaServer Pages). Jest to spowodowane tym, że strony JSP w rzeczywistości przechodzą proces translacji (są kompilowane przez specjalny silnik) do postaci serwletu.

Przykład

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/hi")
public class HelloServlet extends HttpServlet {
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = request.getParameter("name");
		response.getWriter().write("Hello " + name);
	}
	
}

Po wysłaniu żądania np. z przeglądarki pod adres naszaAplikacja/hi?name=Jan w odpowiedzi zobaczymy powitanie:

servlet in firefox

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.