Сервлет является интерфейсом программирования JAVA-приложения (API), работающий на машине сервера, которая может прервать запросы, выполненные клиентом, и может генерировать/отправить ответ соответственно.

Сервлеты

Сервлет является интерфейсом программирования JAVA-приложения (API), работающий на машине сервера, которая может прервать запросы, выполненные клиентом, и может генерировать/отправить ответ соответственно. Известный пример HttpServlet который предоставляет методы для зацепления Запросов HTTP с помощью популярных методов HTTP такой как GET и POST. Можно настроить HttpServlets для слушания на определенном шаблоне URL HTTP, который настраивается в web.xml, или позже с Java EE 6, с @WebServlet аннотация. Многие Java веб-платформы EE создаются сверху сервлетов, таких как JSF, JAX-RS, Spring MVC, Struts, Калитка, и так далее. См. также, Каково различие между JSF, Сервлетом и JSP?

Жизненный цикл

Когда Сервлет требуют впервые или когда веб-приложение запустит, контейнер сервлета создаст экземпляр его и сохранит его в памяти в течение времени жизни веб-приложения. Тот же экземпляр будет снова использован для каждого входящего запроса, URL которого соответствует шаблону URL сервлета. Можно получить доступ к запрошенным данным HttpServletRequest и обработайте ответ HttpServletResponse. Оба объекта доступны как аргументы метода в любом из переопределенных методов HttpServlet, такой как doGet() предварительно обрабатывать запрос и doPost() выполнять последующую обработку запрос. См. также, Как сервлеты работают? Инстанцирование, сессии, совместно используемые переменные и многопоточность.

Установка

Для выполнения Сервлетов Вам нужно:

  • JDK (JRE только достаточен, если сервер имеет свой собственный компилятор).
  • Контейнер сервлета.
  • Дополнительно, Java EE осведомленный IDE (Интегрированный Редактор Разработки).

Существует несколько контейнеров сервлета.

Существуют также серверы JAVA EE-приложения, которые в свою очередь также содержат контейнер сервлета помимо другого Java API EE, такие как JSF, JPA, EJB, и т.д. См. также, Что такое точно Java EE?

Установка контейнера сервлета является обычно просто вопросом загрузки zip/gz файла и извлечения его в местоположении по Вашему выбору.

Обычно также требуется использовать IDE, такой как Eclipse, IntelliJ или Netbeans, таким образом, Вы не должны вручную компилировать и создавать исходные файлы с javac много раз. Достойные IDE имеют плагины, чтобы эффективно интегрировать контейнер сервлета и импортировать необходимый Java API EE в путь сборки проекта. См. также, Как я импортирую javax.servlet API в своем проекте Eclipse?

Привет Мировой № 1 (выполняют последующую обработку запрос),

Последующая обработка запроса, такого как представление и проверка формы POST является обычно известным вариантом использования для сервлета. action атрибут HTML <form> может указать на URL сервлета и method="post" инициировал бы сервлет doPost() метод, где у Вас есть вся свобода управлять Запросом HTTP и ответом.

Предположение, что существует JSP в /WEB-INF/hello.jsp который похож на это...

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <!DOCTYPE html> <html lang="en"> <head> <title>Servlet Hello World</title> <style>.error { color: red; } .success { color: green; }</style> </head> <body> <form action="hello" method="post"> <h1>Hello</h1> <p> <label for="name">What's your name?</label> <input id="name" name="name" value="${fn:escapeXml(param.name)}"> <span class="error">${messages.name}</span> </p> <p> <label for="age">What's your age?</label> <input id="age" name="age" value="${fn:escapeXml(param.age)}"> <span class="error">${messages.age}</span> </p> <p> <input type="submit"> <span class="success">${messages.success}</span> </p> </form> </body> </html> 

( fn:escapeXml() должен защитить Вашу страницу от XSS при восстановлении изображения управляемого пользователями входа; если JSTL не работает в целом, то, вероятно, Ваш контейнер сервлета не поддерживает его из поля (как Tomcat); можно установить его, просто отбросив jstl-1.2.jar в /WEB-INF/lib, см. также страницу информации о JSTL),

... вот то, как com.example.controller.HelloServlet класс должен посмотреть:

package com.example.controller; import java.io.IOException; import java.util.HashMap; import java.util.Map; 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("/hello") public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Preprocess request: we actually don't need to do any business stuff, so just display JSP. request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Postprocess request: gather and validate submitted data and display the result in the same JSP. // Prepare messages. Map<String, String> messages = new HashMap<String, String>(); request.setAttribute("messages", messages); // Get and validate name. String name = request.getParameter("name"); if (name == null || name.trim().isEmpty()) { messages.put("name", "Please enter name"); } else if (!name.matches("\\p{Alnum}+")) { messages.put("name", "Please enter alphanumeric characters only"); } // Get and validate age. String age = request.getParameter("age"); if (age == null || age.trim().isEmpty()) { messages.put("age", "Please enter age"); } else if (!age.matches("\\d+")) { messages.put("age", "Please enter digits only"); } // No validation errors? Do the business job! if (messages.isEmpty()) { messages.put("success", String.format("Hello, your name is %s and your age is %s!", name, age)); } request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response); } } 

Скомпилируйте код и вставьте его /WEB-INF/classes папка. В данном случае файл класса должен закончиться в /WEB-INF/classes/com/example/controller/HelloServlet.class. IDE как Eclipse, Netbeans или IntelliJ сделает все это автоматически при создании динамического веб-проекта.

Обратите внимание что @WebServlet аннотация только работает над Java EE 6 / Сервлет 3,0 способных контейнера (Tomcat 7, Glassfish 3, JBoss AS 6, и т.д.) и если a /WEB-INF/web.xml файл присутствует, затем <web-app> корневое объявление должно соответствовать Сервлет 3,0 версии также.

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> </web-app> 

Если Вы используете/предназначаетесь более старую версию Сервлета, такую как Сервлет 2.5, то необходимо удалить аннотацию и отобразить сервлет в /WEB-INF/web.xml файл следующим образом, который делает эффективно то же самое:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.example.controller.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> 

Так или иначе это в основном говорит контейнеру сервлета, что должно сделать следующее под покрытиями:

HelloServlet helloServlet = new HelloServlet(); // Construct servlet. helloServlet.init(servletConfig); // Initialize servlet with config. helloServlet.init(); // Initialize servlet without config. servlets.put("/hello", helloServlet); // Add to servlet mapping. 

Разверните веб-приложение и перейдите к http://localhost:8080/contextname/hello (без .jsp расширения!) для открытия страницы Hello World. Когда Вы открываете страницу как это, вводя URL в строку поиска или переходя по ссылке или закладке, затем HTTP GET запрос будет запущен и сервлет doGet() метод назовут. Когда форма с method="post" отправлен на URL сервлета, затем HTTP POST запрос будет запущен и сервлет doPost() метод назовут.

Обратите внимание, что JSP помещен в /WEB-INF папка для предотвращения прямого доступа к JSP, когда пользователь вводит его URL в адресную строку браузера. Это обязательно, когда это требуется, чтобы вызывать сервлет doGet() метод перед JSP отображен, например, когда некоторые данные должны быть предварительно загружены.

Привет Мировой № 2 (предварительно обрабатывают запрос),

Предварительная обработка запроса, такого как предварительно загружение списка, который должен быть сразу представлен на "простой ванили", ПОЛУЧАЕТ запрос (который используется, когда Вы переходите по ссылке или входите, URL в браузере обращаются), реже известный вариант использования для сервлета. В то время как это используется широко в реальном мире также, среднее основное учебное руководство по Сервлету, найденное в Интернете, не объясняет это вообще. Однако это довольно легко: просто необходимо реализовать бизнес-задание в doGet() метод вместо в doPost().

Вот основной пример начала, откуда мы получаем список продуктов базы данных так, чтобы это могло быть представлено сразу, когда конечный пользователь открывает страницу продукта интернет-магазина. Только ProductService класс в ниже примера является другим пользовательским классом и не описанный в этой Wiki, так как это выходит за рамки, но list() метод должен быть достаточно простым. Ниже примера предполагает, что это EJB, но это может быть что-либо, см. также, например, это сообщение.

package com.example.controller; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.example.business.ProductService; import com.example.model.Product; @WebServlet("/products") public class ProductServlet extends HttpServlet { @EJB private ProductService productService; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Preprocess request: load list of products for display in JSP. List<Product> products = productService.list(); request.setAttribute("products", products); request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); } } 

Вот то, как /WEB-INF/products.jsp должен посмотреть:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <!DOCTYPE html> <html lang="en"> <head> <title>Our Products</title> </head> <body> <h1>Products</h1> <table> <tr> <th>ID</th> <th>Name</th> <th>Description</th> <th>Price</th> </tr> <c:forEach items="${products}" var="product"> <tr> <td>${product.id}</td> <td><c:out value="${product.name}" /></td> <td><c:out value="${product.description}" /></td> <td><fmt:formatNumber value="${product.price}" type="currency" /></td> </tr> </c:forEach> </table> </body> </html> 

( <c:out> должен защитить Вашу страницу от XSS при восстановлении изображения управляемого пользователями входа, это делает эффективно то же самое как fn:escapeXml())

Разверните веб-приложение и перейдите к http://localhost:8080/contextname/products (без .jsp расширения!). Это будет звонить doGet() метод сервлета, который загружает продукты из DB, хранит его в объеме запроса и передает запрос для представления результатов.

Для получения шага вперед Вы могли отфильтровать продукты на основе параметра запроса, который получен из ПОЛУЧИТЬ поисковой формы следующим образом:

<form action="products"> <input type="text" name="query" /> <input type="submit" value="Search" /> </form> 

или гиперссылка (или закладка) следующим образом:

<a href="products?query=java">Search for products with keyword "java"</a> 

с

String query = request.getParameter("query"); List<Product> products = productService.find(query); // ... 

Это также, как работают поисковые системы как Google!

Стиль кодирования и рекомендации

  • Не называйте a doGet() метод от a doPost() метод или наоборот, или имеют их обоих вызов некоторая другая общепринятая методика как processRequest(). Это неправильно. Каждый из тех двух методов HTTP несет свою собственную ясную ответственность: предварительная обработка или последующая обработка Запроса HTTP. Если Вы намереваетесь зацепить все методы HTTP, необходимо переопределять service() метод. См. также Шаблон Фронтального контроллера.

  • Не производите HTML в сервлете при помощи out.print() операторы. Это только мешает поддерживать. HTML-код принадлежит JSP, где у Вас есть свобода записать HTML путем, Вы хотите, не играя с методами Java и заключенными в кавычки строками. С другой стороны на НЕ используйте scriptlets (встроил необработанный код Java) в файлах JSP. Это только мешает поддерживать. Код Java принадлежит классов Java, где у Вас есть свобода записать Java путем, Вы хотите, не играя с ужасным <% %> вещи. См. также, Как избежать кода Java в файлах JSP?

  • Не использовать <jsp:useBean> если Вы уже используете сервлет для обработки модели. Это только приведет к беспорядку и проблеме обслуживания потому что <jsp:useBean> следует за другим уровнем подхода MVC чем тогда, когда Вы используете сервлеты. Это - или сервлеты или <jsp:useBean>, не оба.

Спецификации

Ресурсы онлайн и учебные руководства

Часто задаваемые вопросы

Связанные теги