Как избежать использования скриптлетов на моей странице JSP?
Мне сказали, что использование скриптлетов (<%= ... %>) на моих страницах JSP не такая уж отличная идея.
Может кто-нибудь с немного большим опытом работы с java / jsp, пожалуйста, подскажите мне, как изменить этот код, чтобы он был более "оптимальным для практики", каким бы это ни было?
Этот JSP на самом деле является моей главной страницей декоратора sitemesh. В основном в моем веб-дизайне есть полоса вкладок и подменю, и я хочу каким-то образом выделить текущую вкладку и показать правильное подменю, посмотрев на URI текущего запроса.
<divclass="submenu"> <c:iftest="${fn:contains(pageContext.request.requestURI, '/events/')}"> <ahref="Listing.action">List of Events</a> |<ahref="New.action">New Event</a> </c:if> <c:iftest="${fn:contains(pageContext.request.requestURI, '/people/')}"> <ahref="Listing.action">List of People</a> |<ahref="New.action">New Person</a> </c:if> </div>
Вот более оптимизированный вариант перезаписи, обратите внимание, что я использовал c:set для "кэширования" результатов выражения для повторного использования и что я использую HTML <base> тег, чтобы не указывать контекстный путь в каждой ссылке (просто сделайте все относительные URL на вашей веб-странице относительно него - без косой черты!):
<divclass="submenu"> <c:iftest="${isEvents}"> <ahref="Listing.action">List of Events</a>|<ahref="New.action">New Event</a> </c:if> <c:iftest="${isPeople}"> <ahref="Listing.action">List of People</a>|<ahref="New.action">New Person</a> </c:if> </div>
На самом деле это можно оптимизировать больше, если вы соберете все эти "жестко запрограммированные" значения, такие как events и people, и свяжете тексты в a Map в области приложения и используете под каждым JSTL <c:forEach> для отображения вкладок.
Что касается вашего актуального вопроса, вы можете отключить скриптлеты (и получать ошибки времени выполнения при их использовании), добавив следующую запись в webapp web.xml. Это может помочь определить наблюдаемые скриптлеты.
Чтобы узнать больше об EL, ознакомьтесь с руководством по Java EE, часть II, глава 5. Неявные объекты EL, такие как ${pageContext} описаны здесь. Чтобы узнать больше о JSTL, ознакомьтесь с руководством по Java EE, часть II, глава 7. Обратите внимание, что JSTL и EL - это две разные вещи. JSTL - это стандартный taglib, а EL просто позволяет программно обращаться к внутренним данным. Хотя он обычно используется в taglibs, таких как JSTL, его также можно использовать отдельно в тексте шаблона.
Ответ 2
Кроме того, является <%= request.getContextPath() %> приемлемым использованием скриптлетов, к которому не так часто относятся неодобрительно?
Это может быть непопулярное мнение, но если все, что вы делаете, это простые условные обозначения и вставки текста, я не могу найти особых недостатков в использовании скриптлетов. (Обратите внимание на если)
Я бы, вероятно, использовал JSTL и язык выражений, но в основном потому, что на нем можно меньше печатать, а поддержка IDE может быть лучше (но хорошая JSP IDE также может обнаружить отсутствующие закрывающие скобки и тому подобное).
Но принципиально (как в "не использовать логику в шаблонах") Я не вижу никакой разницы между
Скриптлеты - не самая плохая вещь в мире. Важное соображение - подумать о том, кто будет поддерживать код. Если его веб-дизайнеры не имеют большого опыта работы с Java, вам, вероятно, лучше использовать библиотеки тегов. Однако, если сопровождением занимаются разработчики Java, им может быть проще перейти на скриптлеты.
Если вы в конечном итоге используете библиотеку тегов и JSTL, вы ожидаете, что сопровождающий также изучит библиотеку тегов и будет знать JSTL. Некоторых разработчиков это устроит, поскольку они хотят или уже обладают этим навыком, но для некоторых разработчиков, которым приходится иметь дело с JSP только раз в несколько месяцев или около того, может быть намного менее болезненной работа с четко написанными скриптлетами, написанными на приятной, знакомой Java.
Ответ 4
Это не прямой ответ на ваш вопрос (и уже есть несколько хороших ответов, поэтому я не буду пытаться дополнять его), но вы упомянули:
Может кто-нибудь с немного большим опытом работы с java / jsp, пожалуйста, подскажите мне, как изменить этот код, чтобы он был более "оптимальным для практики", каким бы это ни было?
На мой взгляд, наилучшей практикой в отношении JSP является то, что его следует использовать строго как механизм создания шаблонов, и не более (т. Е. В нем нет бизнес-логики). Использование JSTL, как многие отмечали, определенно помогает вам достичь этого, но даже с JSTL многое легко сделать в JSP.
Лично мне нравится следовать правилам, изложенным в Обеспечении строгого разделения моделей и представлений в движках создания шаблонов Теренсом Парром при разработке на JSP. В статье упоминается назначение движков шаблонов (разделение модели и представления) и характеристики хорошего движка шаблонов. В ней подробно рассматривается JSP и указывается, почему он не является хорошим движком шаблонов. Неудивительно, что JSP в основном слишком мощный и позволяет разработчикам делать слишком много. Я настоятельно рекомендую прочитать эту статью, она поможет вам ограничиться "хорошими" частями JSP.
Если вы читаете только один раздел в этой статье, прочтите главу 7, которая включает следующие правила:
представление не может изменять модель ни путем прямого изменения объектов данных модели, ни путем вызова методов в модели, которые вызывают побочные эффекты. То есть шаблон может обращаться к данным из модели и вызывать методы, но такие ссылки не должны вызывать побочных эффектов. Это правило частично возникает из-за того, что ссылки на данные не зависят от порядка. Смотрите Раздел 7.1.
представление не может выполнять вычисления для зависимых значений данных потому что вычисления могут измениться в будущем, и в любом случае они должны быть аккуратно инкапсулированы в модель. Например, представление не может вычислять цены продажи книг как “цена в долларах * .90”. Чтобы быть независимым от модели, представление не может делать предположения о значении данных.
представление не может сравнивать зависимые значения данных, но может проверять свойства данных, такие как наличие / отсутствие или длину многозначного значения данных. Тесты типа $ BloodPressure<120 должны быть перенесены в модель, поскольку врачи предпочитают продолжать снижать максимальное систолическое давление у нас. Выражения в представлении должны быть заменены тестом на наличие значения, имитирующего логическое значение, такого как $bloodPressureOk!= null Вывод шаблона может быть обусловлен данными модели и вычислениями, условие просто должно быть вычислено в модели. Даже простые тесты, которые выделяют отрицательные значения красным цветом, должны быть вычислены в модели; правильный уровень абстракции обычно представляет собой что-то более высокое, например, “отдел x теряет деньги”.
представление не может делать предположения о типе данных. Некоторые предположения о типах очевидны, когда представление предполагает, что значением данных является дата, например, но возможны более тонкие предположения о типах: если шаблон предполагает, что $userId является целым числом, разработчик не может изменить это значение на нечисловое в модели, не нарушая шаблон. Это правило запрещает индексирование массива, такое как ColorCode [$ topic] и $ name [$ ID] Представление также не может вызывать методы с аргументами, потому что (статически или динамически) предполагается тип аргумента, если только нельзя гарантировать, что метод модели просто рассматривал их как объекты. Кроме того, графические дизайнеры не программисты; ожидать, что они будут вызывать методы и знать, что передавать, нереально.
Данные из модели не должны содержать информацию об отображении или компоновке. Модель не может передавать в представление какую-либо информацию об отображении, замаскированную под значения данных. Это включает в себя отказ от передачи имени шаблона для применения к другим значениям данных.
Кстати, Теренс создал свой собственный движок для создания шаблонов под названием String Template, который, предположительно, действительно хорошо справляется с обеспечением соблюдения этих правил. У меня нет личного опыта работы с этим, но я хотел бы проверить это в моем следующем проекте.