1. Обзор
Аннотации Java EE облегчают жизнь разработчикам, позволяя им указывать, как компоненты приложения должны вести себя в контейнере. Это современные альтернативы XML-дескрипторам, которые позволяют избежать стандартного кода.
В этой статье мы сосредоточимся на аннотациях, появившихся в Servlet API 3.1 в Java EE 7. Мы рассмотрим их назначение и рассмотрим их использование.
2. Веб-аннотации
Servlet API 3.1 представил новый набор типов аннотаций, которые можно использовать в классах сервлетов :
@WebServlet
@WebInitParam
@Веб-фильтр
@WebListener
@ServletSecurity
@HttpConstraint
@HttpMethodConstraint
@MultipartConfig
Мы рассмотрим их подробно в следующих разделах.
3. @Веб-сервер
Проще говоря, эта аннотация позволяет нам объявлять классы Java как сервлеты :
@WebServlet("/account")
public class AccountServlet extends javax.servlet.http.HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// ...
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// ...
}
}
3.1. Использование атрибутов аннотации @WebServlet
@WebServlet
имеет набор атрибутов, которые позволяют нам настраивать сервлет:
имя
описание
urlPatterns
initParams
Мы можем использовать их, как показано в примере ниже:
@WebServlet(
name = "BankAccountServlet",
description = "Represents a Bank Account and it's transactions",
urlPatterns = {"/account", "/bankAccount" },
initParams = { @WebInitParam(name = "type", value = "savings")})
public class AccountServlet extends javax.servlet.http.HttpServlet {
String accountType = null;
public void init(ServletConfig config) throws ServletException {
// ...
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// ...
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// ...
}
}
Атрибут name
переопределяет имя сервлета по умолчанию, которое по умолчанию является полным именем класса. Если мы хотим предоставить описание того, что делает сервлет, мы можем использовать атрибут description .
Атрибут urlPatterns
используется для указания URL-адресов, по которым доступен сервлет (для этого атрибута можно указать несколько значений, как показано в примере кода).
4. @WebInitParam
Эта аннотация используется с атрибутом initParams аннотации
@WebServlet
и параметрами инициализации сервлета.
В этом примере мы устанавливаем тип
параметра инициализации сервлета в значение «сбережения»:
@WebServlet(
name = "BankAccountServlet",
description = "Represents a Bank Account and it's transactions",
urlPatterns = {"/account", "/bankAccount" },
initParams = { @WebInitParam(name = "type", value = "savings")})
public class AccountServlet extends javax.servlet.http.HttpServlet {
String accountType = null;
public void init(ServletConfig config) throws ServletException {
accountType = config.getInitParameter("type");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// ...
}
}
5. @Веб-фильтр
Если мы хотим изменить запрос и ответ сервлета, не затрагивая его внутреннюю логику, мы можем использовать аннотацию WebFilter
. Мы можем связать фильтры с сервлетом или с группой сервлетов и статическим содержимым, указав шаблон URL.
В приведенном ниже примере мы используем аннотацию @WebFilter
для перенаправления любого несанкционированного доступа на страницу входа:
@WebFilter(
urlPatterns = "/account/*",
filterName = "LoggingFilter",
description = "Filter all account transaction URLs")
public class LogInFilter implements javax.servlet.Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(req.getContextPath() + "/login.jsp");
chain.doFilter(request, response);
}
public void destroy() {
}
}
6. @WebListener
Если нам нужны знания или контроль над тем, как и когда сервлет и его запросы инициализируются или изменяются, мы можем использовать аннотацию @WebListener
.
Чтобы написать веб-слушатель, нам нужно расширить один или несколько из следующих интерфейсов:
ServletContextListener — для
уведомлений о жизненном циклеServletContext
ServletContextAttributeListener — для
уведомлений при изменении атрибутаServletContext
ServletRequestListener — для
уведомлений всякий раз, когда делается запрос на ресурсServletRequestAttributeListener — для
уведомлений о добавлении, удалении или изменении атрибута вServletRequest.
HttpSessionListener — для
уведомлений при создании и уничтожении нового сеанса.HttpSessionAttributeListener — для
уведомлений, когда новый атрибут добавляется или удаляется из сеанса.
Ниже приведен пример того, как мы можем использовать ServletContextListener
для настройки веб-приложения:
@WebListener
public class BankAppServletContextListener
implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("ATTR_DEFAULT_LANGUAGE", "english");
}
public void contextDestroyed(ServletContextEvent sce) {
// ...
}
}
7. @ServletSecurity
Когда мы хотим указать модель безопасности для нашего сервлета, включая роли, контроль доступа и требования аутентификации, мы используем аннотацию @ServletSecurity
.
В этом примере мы ограничим доступ к нашему AccountServlet
с помощью аннотации @ServletSecurity
:
@WebServlet(
name = "BankAccountServlet",
description = "Represents a Bank Account and it's transactions",
urlPatterns = {"/account", "/bankAccount" },
initParams = { @WebInitParam(name = "type", value = "savings")})
@ServletSecurity(
value = @HttpConstraint(rolesAllowed = {"Member"}),
httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"Admin"})})
public class AccountServlet extends javax.servlet.http.HttpServlet {
String accountType = null;
public void init(ServletConfig config) throws ServletException {
// ...
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// ...
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
double accountBalance = 1000d;
String paramDepositAmt = request.getParameter("dep");
double depositAmt = Double.parseDouble(paramDepositAmt);
accountBalance = accountBalance + depositAmt;
PrintWriter writer = response.getWriter();
writer.println("<html> Balance of " + accountType + " account is: " + accountBalance
+ "</html>");
writer.flush();
}
}
В этом случае при вызове AccountServlet
браузер выводит экран входа в систему, чтобы пользователь мог ввести действительное имя пользователя и пароль.
Мы можем использовать аннотации @HttpConstraint
и @HttpMethodConstraint
, чтобы указать значения атрибутов value и
httpMethodConstraints аннотации
@ServletSecurity
.
Аннотация @HttpConstraint
применяется ко всем методам HTTP. Другими словами, он определяет ограничение безопасности по умолчанию.
@HttpConstraint
имеет три атрибута:
ценность
роли разрешены
транспортГарантия
Из этих атрибутов наиболее часто используется атрибут rolesAllowed
. В приведенном выше фрагменте кода примера пользователям, принадлежащим к роли Member
, разрешено вызывать все методы HTTP.
Аннотация @HttpMethodConstraint
позволяет указать ограничения безопасности для конкретного метода HTTP.
@HttpMethodConstraint
имеет следующие атрибуты:
ценность
emptyRoleSemantic
роли разрешены
транспортГарантия
В приведенном выше примере фрагмента кода показано, как метод doPost
ограничен только для пользователей, принадлежащих к роли администратора
, что позволяет выполнять функцию депозита только пользователю с правами администратора
.
8. @MultipartConfig
Эта аннотация используется, когда нам нужно аннотировать сервлет для обработки запросов multipart/form-data
(обычно используется для сервлета File Upload).
Это позволит использовать методы getParts()
и getPart(name)
HttpServletRequest
для доступа ко всем частям, а также к отдельной части.
Загруженный файл можно записать на диск, вызвав write(fileName)
объекта Part.
Теперь мы рассмотрим пример сервлета UploadCustomerDocumentsServlet
, который демонстрирует его использование:
@WebServlet(urlPatterns = { "/uploadCustDocs" })
@MultipartConfig(
fileSizeThreshold = 1024 * 1024 * 20,
maxFileSize = 1024 * 1024 * 20,
maxRequestSize = 1024 * 1024 * 25,
location = "./custDocs")
public class UploadCustomerDocumentsServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
for (Part part : request.getParts()) {
part.write("myFile");
}
}
}
@MultipartConfig
имеет четыре атрибута:
fileSizeThreshold
— это пороговое значение размера при временном сохранении загруженного файла. Если размер загруженного файла больше этого порога, он будет сохранен на диске. В противном случае файл хранится в памяти (размер в байтах)maxFileSize
— это максимальный размер загружаемого файла (размер в байтах).maxRequestSize
— максимальный размер запроса, включая загруженные файлы и другие данные формы (размер в байтах).location
— это каталог, в котором хранятся загруженные файлы.
9. Заключение
В этой статье мы рассмотрели некоторые аннотации Java EE, представленные в Servlet API 3.1, их назначение и использование.
Исходный код, относящийся к этой статье, можно найти на GitHub .