это старый школьный способ кодирования, и в версии JSP 2 существует метод, позволяющий избежать Java-кода в файлах JSP. Каковы альтернативные строки JSP 2 и как называется этот метод?
Переведено автоматически
Ответ 1
Использование скриптлетов (этих <% %> штучек) в JSP действительно крайне не рекомендуется с момента появления taglibs (например, JSTL) и EL (Языка выражений, этих ${} штучек) еще в 2001 году.
Основными недостатками скриптлетов являются:
Возможность повторного использования: вы не можете повторно использовать скриптлеты.
Заменяемость: вы не можете сделать скриптлеты абстрактными.
OO-возможность: вы не можете использовать наследование / композицию.
Возможность отладки: если скриптлет выдает исключение на полпути, все, что вы получаете, - это пустую страницу.
Тестируемость: скриптлеты не поддаются модульному тестированию.
Ремонтопригодность: согласно saldo, требуется больше времени для поддержания логики смешанного / загроможденного / дублированного кода.
Солнце Сам Oracle также рекомендует в соглашениях о кодировании JSP избегать использования скриптлетов всякий раз, когда такая же функциональность возможна с помощью классов (тегов). Вот несколько актуальных примеров:
Из спецификации JSP 1.2 настоятельно рекомендуется использовать стандартную библиотеку тегов JSP (JSTL) в вашем веб-приложении, чтобы помочь уменьшить потребность в скриптлетах JSP на ваших страницах. Страницы, использующие JSTL, в целом легче читать и поддерживать.
...
По возможности, избегайте скриптлетов JSP всякий раз, когда библиотеки тегов предоставляют эквивалентную функциональность. Это упрощает чтение и обслуживание страниц, помогает отделить бизнес-логику от логики представления и упростит превращение ваших страниц в страницы в стиле JSP 2.0 (спецификация JSP 2.0 поддерживает, но не подчеркивает использование скриптлетов).
...
В духе принятия шаблона проектирования model-view-controller (MVC) для уменьшения связи между уровнем представления и бизнес-логикой, скриптлеты JSP не следует использовать для написания бизнес-логики. Скорее, скриптлеты JSP используются при необходимости для преобразования данных (также называемых "объектами значений"), возвращаемых в результате обработки запросов клиента, в надлежащий формат, готовый для клиента. Даже в этом случае это было бы лучше сделать с помощью сервлета front controller или пользовательского тега.
Способ замены скриптлетов полностью зависит от единственной цели кода / логики. Чаще всего этот код должен быть помещен в полноценный класс Java:
Если вы хотите вызывать один и тот же Java-код при каждом запросе, меньше или больше, независимо от запрашиваемой страницы, например, проверяя, вошел ли пользователь в систему, тогда реализуйте фильтр и напишите соответствующий код в doFilter() методе. Например.:
publicvoiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws ServletException, IOException { if (((HttpServletRequest) request).getSession().getAttribute("user") == null) { ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page. } else { chain.doFilter(request, response); // Logged in, just continue request. } }
При отображении на соответствующем, <url-pattern> охватывающем интересующие страницы JSP, вам не нужно копировать один и тот же фрагмент кода на всех страницах JSP.
Если вы хотите вызвать некоторый Java-код для обработки запроса GET, например, предварительно загрузить некоторый список из базы данных для отображения в некоторой таблице, при необходимости на основе некоторых параметров запроса, затем реализуйте сервлет и напишите соответствующий код в doGet() методе. Например.:
protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { try { List<Product> products = productService.list(); // Obtain all products. request.setAttribute("products", products); // Store products in request scope. request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table. } catch (SQLException e) { thrownewServletException("Retrieving products failed!", e); } }
Таким образом, проще работать с исключениями. Доступ к базе данных осуществляется не в разгар рендеринга JSP, а задолго до отображения JSP. У вас по-прежнему есть возможность изменять ответ всякий раз, когда доступ к БД выдает исключение. В приведенном выше примере будет отображаться страница с ошибкой 500 по умолчанию, которую вы в любом случае можете настроить с помощью <error-page> в web.xml.
Если вы хотите вызвать некоторый Java-код для обработки POST-запроса, например, сбора данных из отправленной HTML-формы и выполнения с ними некоторых бизнес-операций (преобразование, проверка, сохранение в БД и т.д.), Затем реализуйте сервлет и напишите соответствующий код в doPost() методе. Например.:
if (user != null) { request.getSession().setAttribute("user", user); // Login user. response.sendRedirect("home"); // Redirect to home page. } else { request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope. request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error. } }
Таким образом, проще работать с разными целевыми страницами результатов: повторно отображать форму с ошибками проверки в случае ошибки (в этом конкретном примере вы можете повторно отобразить ее, используя ${message} in EL) или просто перейти на нужную целевую страницу в случае успеха.
Если вы хотите вызвать некоторый Java-код для управления планом выполнения и / или местом назначения запроса и ответа, затем реализуйте сервлет в соответствии с шаблоном Front Controller в MVC. Например.:
Или просто принять MVC-фреймворк, такой как JSF, Spring MVC, Wicket и т.д., Чтобы в итоге у вас была только страница JSP / Facelets и класс JavaBean без необходимости в пользовательском сервлете.
Если вы хотите вызвать некоторый Java-код для управления потоком внутри страницы JSP, то вам нужно использовать (существующий) taglib для управления потоком, такой как JSTL core. Например. отображение List<Product> в таблице:
С тегами в стиле XML, которые прекрасно вписываются во весь этот HTML, код лучше читается (и, следовательно, лучше обслуживается), чем куча скриптлетов с различными открывающими и закрывающими фигурными скобками ("Где, черт возьми, эта закрывающая фигурная скобка принадлежит?"). Простой способ - настроить ваше веб-приложение на выдачу исключения всякий раз, когда скриптлеты все еще используются, добавив следующую часть в web.xml:
В Facelets, преемнике JSP, который является частью предоставляемого Java EE MVC-фреймворка JSF, уже невозможно использовать скриптлеты. Таким образом, вы автоматически будете вынуждены делать все "правильно".
Если вы хотите вызвать некоторый Java-код для доступа и отображения "внутренних" данных внутри страницы JSP, то вам нужно использовать EL (язык выражений), те ${} вещи. Например. повторное отображение отправленных входных значений:
В ${param.foo} отображается результат request.getParameter("foo").
Если вы хотите вызвать какую-либо утилиту Java-кода непосредственно на странице JSP (обычно public static методы), то вам нужно определить их как EL-функции. В JSTL есть стандартные функции taglib, но вы также можете легко создавать функции самостоятельно. Вот пример того, как JSTL fn:escapeXml полезен для предотвращения XSS-атак.
Обратите внимание, что чувствительность XSS никоим образом не связана конкретно с Java / JSP / JSTL / EL / чем угодно, эту проблему необходимо учитывать в каждом веб-приложении, которое вы разрабатываете. Проблема скриптлетов заключается в том, что он не предоставляет способа встроенных предупреждений, по крайней мере, не используя стандартный Java API. Facelets-преемник JSP уже имеет неявное экранирование HTML, поэтому вам не нужно беспокоиться о дырах XSS в Facelets.
В качестве меры предосторожности: отключите скриптлеты навсегда
Поскольку обсуждается другой вопрос, вы можете и всегда должны отключать скриптлеты в вашем web.xml дескрипторе веб-приложения.
Я бы всегда так делал, чтобы ни один разработчик не добавлял скриптлеты, особенно в крупных компаниях, где вы рано или поздно потеряете обзор. web.xml Настройки выглядят следующим образом: