Как избежать Java-кода в файлах JSP?

Я думаю, что файлы cookie могут быть тем, что вы ищете; это то, как большинство сайтов уникально идентифицируют посетителей.

1619
задан Francesco Menzani 28 August 2015 в 16:17
поделиться

5 ответов

Использование скриптлетов (тех <%%> вещей) в JSP действительно крайне не рекомендуется с момента рождения taglibs (например, JSTL ) и EL ( Expression Language , те $ {} вещи) еще в 2001.

Основные недостатки скриптлетов :

  1. Возможность повторного использования: вы не можете повторно использовать скриптлеты.
  2. Заменяемость: скриптлеты не могут быть абстрактными.
  3. OO-способность: вы не можете использовать наследование / композицию.
  4. Возможность отладки: если скриптлет выдает исключение на полпути, все, что вы получаете, - это пустая страница.
  5. Возможность тестирования: скриптлеты не подлежат модульному тестированию.
  6. Ремонтопригодность: на сальдо требуется больше времени для поддержания логики смешанного / загроможденного / дублированного кода.

Sun Oracle также рекомендует в соглашениях о кодировании JSP избегать использования скриптлетов всякий раз, когда такая же функциональность возможна с помощью (теговых) классов. Вот несколько ссылок, имеющих отношение к делу:

Из спецификации JSP 1.2 настоятельно рекомендуется использовать стандартную библиотеку тегов JSP (JSTL) в вашем веб-приложении, чтобы помочь снизить потребность в сценариях JSP в вашем веб-приложении. страниц. Страницы, использующие JSTL, в целом легче читать и поддерживать.

...

По возможности, избегайте скриптлетов JSP , если библиотеки тегов предоставляют эквивалентную функциональность. Это упрощает чтение и обслуживание страниц, помогает отделить бизнес-логику от логики представления и упростит превращение ваших страниц в страницы в стиле JSP 2.0 (спецификация JSP 2.0 поддерживает, но не подчеркивает использование скриптлетов).

...

В духе принятия шаблона проектирования модель-представление-контроллер (MVC) для уменьшения связи между уровнем представления и бизнес-логикой, скриптлеты JSP не должны использоваться для написание бизнес-логики. Скорее, скриптлеты JSP используются при необходимости для преобразования данных (также называемых «объектами значений»), возвращаемых при обработке клиентских запросов, в надлежащий формат, готовый к работе с клиентом. Даже тогда это лучше было бы сделать с помощью сервлета фронт-контроллера или настраиваемого тега.


Как заменить скриптлеты полностью зависит от единственной цели кода / логики.Чаще всего этот код следует помещать в полноценный класс Java:

  • Если вы хотите вызывать тот же код Java при каждом запросе, меньше или больше независимо от запрашиваемая страница, например проверяя, вошел ли пользователь в систему, затем внедрите фильтр и напишите соответствующий код в методе doFilter () . Например: [

     ]public void doFilter (запрос ServletRequest, ответ ServletResponse, цепочка FilterChain) выбрасывает исключение ServletException, IOException {
    if (((HttpServletRequest) request) .getSession (). getAttribute ("user") == null) {
     ((HttpServletResponse) ответ) .sendRedirect ("логин"); // Не авторизован, перенаправляем на страницу авторизации.
     } еще {
    chain.doFilter (запрос, ответ); // Авторизовались, просто продолжаем запрос.
     }
    }
    

    При отображении на соответствующий , охватывающий интересующие страницы JSP, вам не нужно копировать один и тот же фрагмент кода для всех страниц JSP.


  • Если вы хотите вызвать некоторый Java-код для предварительной обработки запроса, например предварительно загружая некоторый список из базы данных для отображения в какой-либо таблице, если необходимо, на основе некоторых параметров запроса, затем реализуйте сервлет и напишите соответствующий код в методе doGet () . Например: [

     ]protected void doGet (запрос HttpServletRequest, ответ HttpServletResponse) вызывает исключение ServletException, IOException {
    пытаться {
    List  products = productService.list (); // Получить все товары.
    request.setAttribute («товары», товары); // Сохраняем товары в области запроса.
    request.getRequestDispatcher ("/ WEB-INF / products.jsp").вперед (запрос, ответ); // Перенаправить на страницу JSP, чтобы отобразить их в таблице HTML.
     } catch (SQLException e) {
    throw new ServletException («Не удалось получить продукты!», e);}
    }
    

    Таким способом работать с исключениями проще. Доступ к БД не осуществляется во время рендеринга JSP, но задолго до того, как JSP отображается. У вас все еще есть возможность изменить ответ всякий раз, когда доступ к БД вызывает исключение. В приведенном выше примере будет отображаться страница ошибки 500 по умолчанию, которую вы в любом случае можете настроить с помощью в web.xml .


  • Если вы хотите вызвать некоторый Java-код для постобработки запроса, например обрабатывая отправку формы, затем реализуйте сервлет и напишите соответствующий код в методе doPost () . Например: [

     ]protected void doPost (запрос HttpServletRequest, ответ HttpServletResponse) вызывает исключение ServletException, IOException {
    Строка username = request.getParameter ("имя пользователя");
    Строка password = request.getParameter («пароль»);
    Пользователь user = userService.find (имя пользователя, пароль);
    
    if (user! = null) {
    request.getSession (). setAttribute («пользователь», пользователь); // Авторизация пользователя.
    response.sendRedirect ("домой"); // Перенаправление на домашнюю страницу.
     } еще {
    request.setAttribute ("сообщение", "Неизвестное имя пользователя / пароль. Повторите попытку."); // Сохраняем сообщение об ошибке в области запроса.
    request.getRequestDispatcher ("/ WEB-INF / login.jsp"). forward (запрос, ответ); // Перейти на страницу JSP, чтобы повторно отобразить форму входа в систему с ошибкой.}
    }
    

    Таким образом, работать с разными адресатами страницы результатов проще: повторное отображение формы с ошибками проверки в случае ошибки (в этом конкретном примере вы можете повторно отобразить ее, используя $ {message} в EL ) или просто переход на желаемую целевую страницу в случае успеха.


  • Если вы хотите вызвать некоторый Java-код для управления планом выполнения и / или адресатом запроса и ответа, тогда реализуйте сервлет в соответствии с Шаблон фронтального контроллера MVC . Например: [

     ]protected void service (запрос HttpServletRequest, ответ HttpServletResponse) выбрасывает ServletException, IOException {
    пытаться {
    Действие action = ActionFactory.getAction (запрос);
    String view = action.execute (запрос, ответ);
    
    if (view.equals (request.getPathInfo (). substring (1)) {
    request.getRequestDispatcher ("/ WEB-INF /" + просмотр + ".jsp"). forward (запрос, ответ);
     } еще {
    response.sendRedirect (просмотр);
     }
     } catch (Exception e) {
    throw new ServletException («Не удалось выполнить действие.», e);
     }
    }
    

    Или просто используйте платформу MVC, например JSF , Spring MVC , Wicket и т. Д., Чтобы в итоге вы получили только страницу JSP / Facelets и Класс JavaBean без специального сервлета.


  • Если вы хотите вызвать некоторый Java-код для управления потоком внутри страницы JSP, тогда вам нужно получить (существующую) библиотеку тегов управления потоком, например ядро ​​JSTL . Например. отображение List в таблице:

     <% @ taglib uri = "http: //java.sun.com / jsp / jstl / core "prefix =" c "%>
    ...
    <таблица>
     
     
      $ {product.name} 
      $ {product.description} 
      $ {product.price} 
     
     
    
    

    С тегами в стиле XML, которые хорошо вписываются в весь этот HTML, код лучше читается (и, следовательно, лучше обслуживается), чем связка скриптлетов с различными открывающими и закрывающими скобками ( «Где, черт возьми, эта закрывающая скобка? принадлежат? "). Простая помощь - настроить ваше веб-приложение так, чтобы оно генерировало исключение всякий раз, когда скриптлеты все еще используются, добавив следующий фрагмент в web.xml :

     
     
      * .jsp 
      истина 
     
    
    

    В Facelets , преемнике JSP, который является частью Java EE, предоставленной инфраструктурой MVC JSF , уже невозможно использовать скриптлеты . Таким образом, вы автоматически заставляете все делать «правильно».


  • Если вы хотите вызвать некоторый Java-код для доступа и отображения «серверных» данных внутри страницы JSP, тогда вам нужно использовать EL (язык выражений), те $ {} вещи. Например. повторное отображение отправленных входных значений:

     
    

    $ {param.foo} отображает результат request.getParameter ("foo") .


  • Если вы хотите вызвать некоторую утилиту Java-код непосредственно на странице JSP (обычно общедоступные статические методы), то вам необходимо определить их как функции EL. В JSTL есть стандартная библиотека функций , но вы также можете легко создавать функции самостоятельно . Вот пример того, как JSTL fn: escapeXml полезен для предотвращения XSS атак .

     <% @ taglib uri = "http://java.sun.com/jsp/jstl/functions" prefix = "fn"%>
    ...
    

    Обратите внимание, что чувствительность XSS никоим образом не связана конкретно с Java / JSP / JSTL / EL / чем-то еще, эту проблему необходимо учитывать в каждом веб-приложении, которое вы разрабатываете. Проблема скриптлетов заключается в том, что они не обеспечивают встроенных средств предотвращения, по крайней мере, без использования стандартного Java API. Преемник JSP Facelets уже имеет неявное экранирование HTML, поэтому вам не нужно беспокоиться о дырах XSS в Facelets.

См. Также:

1947
ответ дан 22 November 2019 в 20:13
поделиться

Опыт показал, что у JSP есть некоторые недостатки, один из которых состоит в том, что трудно избежать смешивания разметки с реальным кодом.

Если можете, подумайте об использовании специальной технологии для того, что вам нужно. В Java EE 6 есть JSF 2.0, который предоставляет множество полезных функций, включая склейку Java-бинов вместе со страницами JSF с помощью подхода # {bean.method (argument)} .

27
ответ дан 22 November 2019 в 20:13
поделиться

Вы можете использовать Теги JSTL вместе с выражениями EL, чтобы избежать смешения кода Java и HTML:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
    <head>
    </head>
    <body>

        <c:out value="${x + 1}" />
        <c:out value="${param.name}" />
        // and so on

    </body>
</html>
54
ответ дан 22 November 2019 в 20:13
поделиться

Я не уверен, правильно ли я понял.

Вам следует почитать что-нибудь о MVC. Spring MVC и Struts 2 - два наиболее распространенных решения.

60
ответ дан 22 November 2019 в 20:13
поделиться

JSTL предлагает теги для условных выражений, циклов, наборов, получения и т. Д. Например:

<c:if test="${someAttribute == 'something'}">
   ...
</c:if>

JSTL работает с атрибутами запроса - они чаще всего устанавливаются в запросе сервлетом. , который перенаправляет в JSP.

107
ответ дан 22 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: