Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Servlet - основа веб-приложений на Java
Servlet - это Java класс, который обрабатывает HTTP запросы и генерирует HTTP ответы. Это фундамент веб-приложений на Java.
История и роль Servlet
Servlet появился в 1997 году как решение для создания динамических веб-приложений (в то время была только статика). Сегодня Servlet - это стандарт Java EE (Jakarta EE), на котором построены все современные web frameworks: Spring, Jakarta Faces, Apache Struts и другие.
Что такое Servlet на самом деле
Servlet - это interface из Java EE спецификации:
public interface Servlet {
void init(ServletConfig config) throws ServletException;
void service(ServletRequest request, ServletResponse response) throws ServletException, IOException;
void destroy();
ServletConfig getServletConfig();
String getServletInfo();
}
Обычно extends HttpServlet:
public abstract class HttpServlet extends GenericServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { }
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { }
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { }
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { }
}
Жизненный цикл Servlet
public class UserServlet extends HttpServlet {
// 1. Инициализация - вызывается один раз при загрузке
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("Servlet инициализирован");
// Здесь можно загрузить ресурсы, подключиться к БД
}
// 2. Обработка запроса - вызывается для каждого HTTP запроса
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("GET запрос получен");
// Читаем параметры из запроса
String userId = request.getParameter("id");
// Выполняем логику
String userName = getUserName(userId);
// Отправляем ответ
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("<html><body>");
response.getWriter().println("<h1>User: " + userName + "</h1>");
response.getWriter().println("</body></html>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("POST запрос получен");
// Читаем параметры POST
String name = request.getParameter("name");
String email = request.getParameter("email");
// Сохраняем пользователя
saveUser(name, email);
// Перенаправляем
response.sendRedirect("/users");
}
// 3. Очистка - вызывается один раз при выгрузке Servlet'а
@Override
public void destroy() {
System.out.println("Servlet завершает работу");
// Закрываем ресурсы, соединения с БД
}
private String getUserName(String userId) {
// Логика получения имени из БД
return "John Doe";
}
private void saveUser(String name, String email) {
// Логика сохранения в БД
}
}
Архитектура Servlet контейнера
Client (браузер)
| HTTP запрос
v
Web Server (Apache, Nginx)
| Переда на Java приложение
v
Servlet Container (Tomcat, Jetty, JBoss)
| Маршрутизирует на нужный Servlet
v
Servlet (ваш класс)
| Обрабатывает запрос
v
Servlet Container
| Возвращает ответ
v
Web Server
| HTTP ответ
v
Client (браузер) получает ответ
Практический пример: REST API с Servlet
@WebServlet("/api/users/*")
public class UserAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Распарсиваем URL: /api/users/123
String pathInfo = request.getPathInfo(); // Получаем /123
Long userId = extractUserId(pathInfo);
// Получаем пользователя из БД
User user = userService.findById(userId);
if (user == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().write("{\"error\":\"User not found\"}");
return;
}
// JSON ответ
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
String json = objectMapper.writeValueAsString(user);
response.getWriter().write(json);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Читаем JSON из body
String body = readRequestBody(request);
User newUser = objectMapper.readValue(body, User.class);
// Сохраняем
User savedUser = userService.save(newUser);
// Возвращаем созданного пользователя
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType("application/json");
response.setHeader("Location", "/api/users/" + savedUser.getId());
response.getWriter().write(objectMapper.writeValueAsString(savedUser));
}
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
Long userId = extractUserId(pathInfo);
userService.deleteById(userId);
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
private Long extractUserId(String pathInfo) {
// /123 -> 123
return Long.parseLong(pathInfo.substring(1));
}
private String readRequestBody(HttpServletRequest request) throws IOException {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
return sb.toString();
}
}
Servlet конфигурация
Через @WebServlet аннотацию (Servlet 3.0+)
@WebServlet("mapping/path")
public class MyServlet extends HttpServlet { }
@WebServlet("/users") // GET /users
public class UsersServlet extends HttpServlet { }
@WebServlet("/api/users/*") // GET /api/users/*, /api/users/123
public class UserAPIServlet extends HttpServlet { }
Через web.xml (старый способ)
<web-app>
<servlet>
<servlet-name>userServlet</servlet-name>
<servlet-class>com.example.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/users</url-pattern>
</servlet-mapping>
</web-app>
ServletRequest и ServletResponse
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// HttpServletRequest - получение данных от клиента
String param = request.getParameter("key"); // Параметр
String header = request.getHeader("User-Agent"); // Заголовок
String method = request.getMethod(); // GET, POST, PUT...
String path = request.getPathInfo(); // Путь
int port = request.getServerPort(); // Порт сервера
HttpSession session = request.getSession(); // Сессия
Cookie[] cookies = request.getCookies(); // Cookies
// HttpServletResponse - отправка ответа клиенту
response.setStatus(200); // HTTP статус
response.setContentType("text/html;charset=UTF-8"); // Content-Type
response.setHeader("Custom-Header", "value"); // Заголовок
response.addCookie(new Cookie("name", "value")); // Cookie
PrintWriter writer = response.getWriter();
writer.println("Ответ");
}
Сессии в Servlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Получаем или создаем сессию
HttpSession session = request.getSession(true);
// Сохраняем данные в сессию
session.setAttribute("userId", 123);
session.setAttribute("username", "john_doe");
// Читаем из сессии
Object userId = session.getAttribute("userId");
// Удаляем сессию
session.invalidate();
}
Filter и Servlet
Filer'ы перехватывают запросы ДО Servlet'а:
@WebFilter("/*") // Все запросы
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Запрос до Servlet: " + request);
// Передаем дальше
chain.doFilter(request, response);
System.out.println("Ответ после Servlet");
}
}
Современный подход: Spring Framework
В современных приложениях Servlet'ы используются опосредованно через Spring:
// Spring под капотом использует DispatcherServlet
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}
// Spring наследует от HttpServlet и обрабатывает запросы
// @Controller методы вызываются из Servlet'а
Когда использовать Servlet напрямую
- Низкоуровневая обработка - HTTP запросов
- Специфичные requirements - file upload, streaming
- Legacycode - старые приложения
- Performance critical - когда нужна полная контроль
Обычно используешь Spring, но понимание Servlet'ов - обязательно для хорошего Java разработчика.
Резюме
- Servlet - основной компонент Java веб-приложений
- Жизненный цикл - init → doGet/doPost/... → destroy
- Контейнер - Tomcat, Jetty управляют Servlet'ами
- Современный подход - Spring скрывает Servlet'ы, но они есть под капотом
- Обязательно знать - даже если не пишешь их напрямую