Как избежать Java-кода в файлах JSP?
Я новичок в Java EE и знаю, что-то вроде следующих трех строк
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
это старый способ кодирования, и в JSP версии 2 существует метод, позволяющий избежать Java-кода в файлах JSP. Может кто-нибудь сказать, пожалуйста, альтернативные линии JSP 2, и как называется эта техника?
32 ответа
Использование скриптлетов (тех <% %>
вещей) в JSP действительно крайне не рекомендуется с рождения taglibs (например, JSTL) и EL ( Expression Language, те, ${}
вещи) еще в 2001 году.
Основными недостатками скриплетов являются:
- Возможность повторного использования: вы не можете повторно использовать скриптлеты.
- Заменимость: вы не можете сделать скриптлеты абстрактными.
- ОО-способность: вы не можете использовать наследование / композицию.
- Отладка: еслискриптлет выбрасывает исключение на полпути, вы получаете только пустую страницу.
- Тестируемость: скриптлеты не тестируются юнитами.
- Ремонтопригодность: для сохранения логики смешанного / загроможденного / дублированного кода требуется больше времени.
Сам 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 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-код дляпредварительной обработки запроса, например, предварительно загрузить некоторый список из базы данных для отображения в некоторой таблице, при необходимости, основываясь на некоторых параметрах запроса, тогда реализуйте сервлет и напишите код соответствующим образом в
doGet()
метод. Например:protected void doGet(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) { throw new ServletException("Retrieving products failed!", e); } }
Так легче справляться с исключениями. К БД не обращаются во время рендеринга JSP, но задолго до того, как JSP был отображен. У вас все еще есть возможность изменить ответ всякий раз, когда доступ к БД вызывает исключение. В приведенном выше примере будет отображена страница ошибки 500 по умолчанию, которую вы в любом случае можете настроить с помощью
<error-page>
вweb.xml
,Если вы хотите вызвать некоторый Java-код для постобработки запроса, например, обработки отправки формы, то реализуйте сервлет и напишите код соответственно
doPost()
метод. Например:protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); User user = userService.find(username, password); 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}
в EL) или просто переход на нужную целевую страницу в случае успеха.Если вы хотите вызвать некоторый Java-код для управления планом выполнения и / или местом назначения запроса и ответа, то реализуйте сервлет в соответствии с шаблоном фронт-контроллера MVC. Например:
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Action action = ActionFactory.getAction(request); String view = action.execute(request, response); if (view.equals(request.getPathInfo().substring(1)) { request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response); } else { response.sendRedirect(view); } } catch (Exception e) { throw new ServletException("Executing action failed.", e); } }
Или просто используйте MVC-фреймворк, такой как JSF, Spring MVC, Wicket и т. Д., Чтобы в итоге вы получили только страницу JSP/Facelets и класс JavaBean без необходимости использования собственного сервлета.
Если вы хотите вызвать некоторый Java-код для управления потоком внутри страницы JSP, то вам нужно получить (существующий) taglib управления потоком, такой как ядро JSTL. Например, отображение
List<Product>
в таблице:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> ... <table> <c:forEach items="${products}" var="product"> <tr> <td>${product.name}</td> <td>${product.description}</td> <td>${product.price}</td> </tr> </c:forEach> </table>
С тегами в стиле XML, которые хорошо вписываются в этот HTML, код лучше читается (и, следовательно, лучше поддерживается), чем набор скриплетов с различными открывающими и закрывающими скобками ("Куда, черт возьми, относится эта закрывающая скобка?"). Простой способ - настроить ваше веб-приложение так, чтобы оно вызывало исключение, когда скриптлеты все еще используются, добавив следующую часть в
web.xml
:<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group> </jsp-config>
В Facelets, преемнике JSP, который является частью Java EE, предоставленной инфраструктуре MVC JSF, уже невозможно использовать скриптлеты. Таким образом, вы автоматически будете вынуждены делать все правильно.
Если вы хотите вызвать некоторый Java-код для доступа и отображения "внутренних данных" на странице JSP, то вам нужно использовать EL (Expression Language), эти
${}
вещи. Например, повторное отображение введенных значений ввода:<input type="text" name="foo" value="${param.foo}" />
${param.foo}
отображает результатrequest.getParameter("foo")
,Если вы хотите вызвать некоторый служебный Java-код прямо на странице JSP (обычно
public static
методы), то вам нужно определить их как функции EL. В JSTL есть стандартные функции taglib, но вы также можете легко создавать функции самостоятельно. Вот пример того, как JSTLfn:escapeXml
полезно для предотвращения атак XSS.<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> ... <input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
Обратите внимание, что чувствительность XSS никоим образом не связана конкретно с Java/JSP/JSTL/EL/ чем бы то ни было, эту проблему необходимо учитывать в каждом разрабатываемом веб-приложении. Проблема скриплетов заключается в том, что они не предоставляют встроенных предупреждений, по крайней мере, не используя стандартный Java API. Преемник JSP Facelets уже неявно экранирует HTML, поэтому вам не нужно беспокоиться о дырах XSS в Facelets.
Смотрите также:
В качестве меры предосторожности: отключите скрипты насовсем
Поскольку другой вопрос обсуждается, вы можете и всегда должны отключать скриптлеты в своем web.xml
дескриптор веб-приложения.
Я всегда делал бы это, чтобы не допустить добавления разработчиками скриплетов, особенно в крупных компаниях, где вы рано или поздно потеряете обзор. web.xml
Настройки выглядят так:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
JSTL предлагает теги для условных выражений, циклов, множеств, наборов и т. Д. Например:
<c:if test="${someAttribute == 'something'}">
...
</c:if>
JSTL работает с атрибутами запроса - они чаще всего устанавливаются в запросе сервлетом, который перенаправляет в JSP.
Я не уверен, правильно ли я понял.
Вы должны прочитать кое-что о MVC. Spring MVC & Struts 2 являются двумя наиболее распространенными решениями.
Вы можете использовать теги 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>
Есть также основанные на компонентах фреймворки, такие как Wicket, которые генерируют много HTML для вас. Тэги, которые заканчиваются в HTML, являются чрезвычайно простыми, и в них практически отсутствует смешанная логика. В результате получаются почти пустые HTML-страницы с типичными HTML-элементами. Недостатком является то, что в Wicket API есть много компонентов для изучения, и некоторые вещи могут быть труднодостижимы при этих ограничениях.
В архитектурном шаблоне MVC JSP представляют слой View. Встраивание кода Java в JSP считается плохой практикой. Вы можете использовать JSTL, freeMarker, скорость с JSP в качестве "движка шаблонов". Поставщик данных для этих тегов зависит от структур, с которыми вы имеете дело. Struts 2
а также webwork
В качестве реализации для MVC Pattern используется OGNL "очень интересная техника для представления свойств Beans в JSP ".
Опыт показывает, что у JSP есть некоторые недостатки, одним из которых является сложность, чтобы избежать смешивания разметки с реальным кодом.
Если вы можете, то подумайте об использовании специализированной технологии для того, что вам нужно сделать. В Java EE 6 есть JSF 2.0, который предоставляет множество полезных функций, включая склейку Java-бинов вместе со страницами JSF через #{bean.method(argument)}
подход.
Если вы просто хотите избежать недостатков Java-кодирования в JSP, вы можете сделать это даже с помощью скриптов. Просто следуйте некоторой дисциплине, чтобы иметь минимальный Java в JSP и почти нет вычислений и логики на странице JSP.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%//instantiate a JSP controller
MyController clr = new MyController(request, response);
//process action if any
clr.process(request);
//process page forwaring if necessary
//do all variable assignment here
String showMe = clr.getShowMe();%>
<html>
<head>
</head>
<body>
<form name="frm1">
<p><%= showMe %>
<p><% for(String str : clr.listOfStrings()) { %>
<p><%= str %><% } %>
// and so on
</form>
</body>
</html>
Научитесь настраивать и писать свои собственные теги, используя JSTL
Обратите внимание, что EL - это EviL (исключения времени выполнения, рефакторинг)
Калитка тоже может быть злой (производительность, утомительная для небольших приложений или простой уровень просмотра)
Пример из java2s,
Это должно быть добавлено в web.xml веб-приложения
<taglib>
<taglib-uri>/java2s</taglib-uri>
<taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>
создать файл:java2s.tld в /WEB-INF/
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- a tab library descriptor -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Java2s Simple Tags</short-name>
<!-- this tag manipulates its body content by converting it to upper case
-->
<tag>
<name>bodyContentTag</name>
<tag-class>com.java2s.BodyContentTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>howMany</name>
</attribute>
</tag>
</taglib>
скомпилируйте следующий код в WEB-INF\classes\com\java2s
package com.java2s;
import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class BodyContentTag extends BodyTagSupport{
private int iterations, howMany;
public void setHowMany(int i){
this.howMany = i;
}
public void setBodyContent(BodyContent bc){
super.setBodyContent(bc);
System.out.println("BodyContent = '" + bc.getString() + "'");
}
public int doAfterBody(){
try{
BodyContent bodyContent = super.getBodyContent();
String bodyString = bodyContent.getString();
JspWriter out = bodyContent.getEnclosingWriter();
if ( iterations % 2 == 0 )
out.print(bodyString.toLowerCase());
else
out.print(bodyString.toUpperCase());
iterations++;
bodyContent.clear(); // empty buffer for next evaluation
}
catch (IOException e) {
System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
e.printStackTrace();
} // end of catch
int retValue = SKIP_BODY;
if ( iterations < howMany )
retValue = EVAL_BODY_AGAIN;
return retValue;
}
}
Запустите сервер и загрузите bodyContent.jsp в браузер
<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
<head>
<title>A custom tag: body content</title>
</head>
<body>
This page uses a custom tag manipulates its body content.Here is its output:
<ol>
<java2s:bodyContentTag howMany="3">
<li>java2s.com</li>
</java2s:bodyContentTag>
</ol>
</body>
</html>
Wicket также является альтернативой, которая полностью отделяет java от html, поэтому дизайнер и программист могут работать вместе и над разными наборами кода, мало понимая друг друга.
Посмотри на калитку.
Вы задали хороший вопрос, и, хотя вы получили хорошие ответы, я бы посоветовал вам избавиться от JSP. Это устаревшая технология, которая в конечном итоге умрет. Используйте современный подход, например, шаблонизаторы. У вас будет очень четкое разделение бизнес-уровня и уровня представления, и, конечно, не будет Java-кода в шаблонах, поэтому вы сможете создавать шаблоны непосредственно из программного обеспечения для редактирования веб-презентаций, в большинстве случаев используя WYSIWYG.
И, конечно же, держитесь подальше от фильтров, предварительной и постобработки, иначе вы можете столкнуться с трудностями поддержки / отладки, поскольку вы всегда не знаете, где переменная получает значение.
Чтобы избежать java-кода в JSP-файлах, java теперь предоставляет библиотеки тегов, такие как JSTL, также java предлагает JSF, в который вы можете записывать все программные структуры в виде тегов.
Независимо от того, сколько вы пытаетесь избежать, когда вы работаете с другими разработчиками, некоторые из них по-прежнему предпочитают скриптлет и затем вставляют злой код в проект. Поэтому настройка проекта при первом знаке очень важна, если вы действительно хотите уменьшить код скриптлета. Есть несколько методов, чтобы преодолеть это (в том числе несколько фреймворков, которые другие упоминали). Однако, если вы предпочитаете чистый способ JSP, используйте файл тегов JSTL. Приятно то, что вы также можете настроить главные страницы для своего проекта, чтобы другие страницы могли наследовать главные страницы
Создайте главную страницу под названием base.tag под вашими тегами WEB-INF/ со следующим содержанием
<%@tag description="Overall Page template" pageEncoding="UTF-8"%> <%@attribute name="title" fragment="true" %> <html> <head> <title> <jsp:invoke fragment="title"></jsp:invoke> </title> </head> <body> <div id="page-header"> .... </div> <div id="page-body"> <jsp:doBody/> </div> <div id="page-footer"> ..... </div> </body> </html>
На этой главной странице я создал фрагмент с названием "title", чтобы на дочерней странице я мог вставить больше кодов в это место главной страницы. Также тег <jsp:doBody/>
будет заменено содержимым дочерней страницы
Создайте дочернюю страницу (child.jsp) в папке WebContent:
<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %> <t:base> <jsp:attribute name="title"> <bean:message key="hello.world" /> </jsp:attribute> <jsp:body> [Put your content of the child here] </jsp:body> </t:base>
<t:base>
используется для указания главной страницы, которую вы хотите использовать (в данный момент это base.tag). Весь контент внутри тега <jsp:body>
здесь заменит <jsp:doBody/>
на вашей главной странице. Ваша дочерняя страница также может содержать любой тег lib, и вы можете использовать его, как и другие упомянутые выше. Однако, если вы используете какой-либо код скриптлета здесь (<%= request.getParameter("name") %>
...) и попробуйте запустить эту страницу, вы получите JasperException because Scripting elements ( <%!, <jsp:declaration, <%=, <jsp:expression, <%, <jsp:scriptlet ) are disallowed here
, Поэтому другие люди не могут включить злой код в файл jsp.
Вызов этой страницы с вашего контроллера:
Вы можете легко вызвать файл child.jsp с вашего контроллера. Это также хорошо работает со структурой стоек
Использование JSTL Tag libraries
в JSP это будет работать идеально.
Если кто-то действительно против программирования на большем количестве языков, чем один, я предлагаю GWT, теоретически вы можете избежать всех элементов JS и HTML, поскольку Google Toolkit преобразует весь клиентский и общий код в JS, у вас не будет проблем с ними, поэтому у вас есть веб-сервис без кодирования на других языках. Даже вы можете использовать какой-то CSS по умолчанию откуда-то, как это задано расширениями (smartGWT или Vaadin). Вам не нужно изучать десятки аннотаций.
Конечно, если вы хотите, вы можете взломать себя до глубины кода и внедрить JS и обогатить свою HTML-страницу, но на самом деле вы можете избежать этого, если хотите, и результат будет хорошим, как это было написано в любой другой среде. Я говорю, что стоит попробовать, и основной GWT хорошо документирован.
И, конечно же, многие коллеги-программисты описывают или рекомендуют несколько других решений. GWT предназначен для людей, которые действительно не хотят иметь дело с веб-частью или минимизировать ее.
Использование скриптлетов в JSP не является хорошей практикой.
Вместо этого вы можете использовать:
- JSTL теги
- EL выражения
- Пользовательские теги - вы можете определить свои собственные теги для использования.
Пожалуйста, обратитесь к:
Отличная идея из мира Python - это языки атрибутов Template; TAL был введен Zope (следовательно, "Шаблоны страниц Zope", ZPT) и является стандартом, также с реализациями на PHP, XSLT и Java (я использовал инкарнации Python/Zope и PHP). В этом классе шаблонных языков один приведенный выше пример может выглядеть так:
<table>
<tr tal:repeat="product products">
<td tal:content="product/name">Example product</td>
<td tal:content="product/description">A nice description</td>
<td tal:content="product/price">1.23</td>
</tr>
</table>
Код выглядит как обычный HTML (или XHTML) плюс некоторые специальные атрибуты в пространстве имен XML; его можно просмотреть с помощью браузера и безопасно настроить дизайнером. Также есть поддержка макросов и i18n:
<h1 i18n:translate="">Our special offers</h1>
<table>
<tr tal:repeat="product products">
<td tal:content="product/name"
i18n:translate="">Example product</td>
<td tal:content="product/description"
i18n:translate="">A nice description</td>
<td tal:content="product/price">1.23</td>
</tr>
</table>
Если доступны переводы контента, они используются.
Хотя я не очень разбираюсь в реализации Java.
Конечно, замени <%! counter++; %>
с помощью архитектуры производителя событий-потребителей, где бизнес-уровень уведомляется о необходимости увеличения счетчика, он соответствующим образом реагирует и уведомляет докладчиков, чтобы они обновили представления. В этом участвует ряд транзакций базы данных, поскольку в будущем нам нужно будет знать новое и старое значение счетчика, кто его увеличил и с какой целью. Очевидно, что это связано с сериализацией, так как слои полностью отделены друг от друга. Вы сможете увеличить свой счетчик по RMI, IIOP, SOAP. Но требуется только HTML, который вы не реализуете, поскольку это такой обыденный случай. Ваша новая цель - достичь 250 приращений в секунду на вашем новом блестящем сервере E7, 64 ГБ ОЗУ.
Я занимаюсь программированием более 20 лет, большинство проектов проваливаются до появления секстета: возможность многократного использования Возможность замены ОО-способность Отлаживаемость Тестируемость Требуется даже ремонтопригодность. Другие проекты, выполняемые людьми, которые заботились только о функциональности, были чрезвычайно успешными. Кроме того, жесткая объектная структура, реализованная слишком рано в проекте, делает код неспособным адаптироваться к резким изменениям в спецификациях (иначе говоря, гибким).
Таким образом, я рассматриваю как промедление деятельность по определению "слоев" или избыточных структур данных либо в начале проекта, либо когда это не требуется специально.
Технически все JSP преобразуются в сервлеты во время выполнения. Изначально JSP был создан с целью разделения бизнес-логики и логики проектирования в соответствии с шаблоном MVC. Таким образом, JSP технически - это все java-коды во время выполнения. Но чтобы ответить на этот вопрос, библиотеки тегов обычно используются для применения логики (удаления кодов Java) к страницам JSP.
Если мы используем следующие вещи в веб-приложении Java, код Java может быть удален с переднего плана JSP.
Использовать архитектуру MVC для веб-приложения
Используйте теги JSP
а. Стандартные теги
б. Пользовательские теги
Язык выражения
Как избежать Java-кода в файлах JSP?
Вы можете использовать теги библиотеки вкладок, такие как JSTL, в дополнение к языку выражений (EL). Но EL плохо работает с JSP. Так что, вероятно, лучше полностью отказаться от JSP и использовать Facelets.
Facelets - это первый не-JSP язык объявления страниц, разработанный для JSF (Java Server Faces), который предоставил разработчикам JSF более простую и мощную модель программирования по сравнению с JSP. Это решает различные проблемы, возникающие в JSP для разработки веб-приложений.
Использование Scriptlets является очень старым способом и не рекомендуется. Если вы хотите напрямую что-то выводить на своих страницах JSP, просто используйте язык выражений (EL) вместе с JSTL.
Есть и другие варианты, такие как использование шаблонизатора, такого как Velocity, Freemarker, Thymeleaf и т. Д. Но использование простой JSP с EL и JSTL служит моей цели большую часть времени, и это также кажется самым простым для новичка.
Кроме того, обратите внимание, что не рекомендуется использовать бизнес-логику на уровне представления, вы должны выполнять свою бизнес-логику на уровне службы и передавать результат вывода в представления через контроллер.
Ничего из этого больше не используется, мой друг, мой совет - отделить представление (css, html, javascript и т. Д.) От сервера.
В моем случае мои системы обрабатывают представление с помощью Angular, и любые необходимые данные доставляются с сервера с использованием служб отдыха.
Поверьте, это изменит ваш дизайн
Используйте основу, угловой, как javascript framework для дизайна пользовательского интерфейса и извлекайте данные с помощью rest api. Это полностью удалит Java-зависимость из пользовательского интерфейса.
JSP 2.0 имеет функцию под названием "Файлы тегов", вы можете писать теги без внешних java
код и tld
, Вам нужно создать .tag
файл и положить его в WEB-INF\tags
Вы даже можете создать структуру каталогов для упаковки ваших тегов.
Например:
/WEB-INF/tags/html/label.tag
<%@tag description="Rensders a label with required css class" pageEncoding="UTF-8"%>
<%@attribute name="name" required="true" description="The label"%>
<label class="control-label control-default" id="${name}Label">${name}</label>
Используйте это как
<%@ taglib prefix="h" tagdir="/WEB-INF/tags/html"%>
<h:label name="customer name" />
Также вы можете легко прочитать тело тега
/WEB-INF/tags/html/bold.tag
<%@tag description="Bold tag" pageEncoding="UTF-8"%>
<b>
<jsp:doBody/>
</b>
Используй это
<%@ taglib prefix="h" tagdir="/WEB-INF/tags/bold"%>
<h:bold>Make me bold</h:bold>
Примеры очень просты, но вы можете выполнить здесь много сложных задач. Пожалуйста, учтите, что вы можете использовать другие теги (например: JSTL
который имеет управляющие теги, такие как if/forEcah/chosen
текстовые манипуляции, как format/contains/uppercase
или даже теги SQL select/update
), передайте все добрые параметры, например Hashmap
, доступ session
, request
... в вашем файле тегов тоже.
Файл тегов настолько прост в разработке, что вам не нужно было перезагружать сервер при их изменении, как файлы jsp. Это облегчает их разработку.
Даже если вы используете фреймворк наподобие Struts 2, в котором есть много хороших тегов, вы можете обнаружить, что наличие собственных тегов может значительно уменьшить ваш код. Вы можете передать параметры вашего тега в распорки и таким образом настроить тег вашего фреймворка.
Вы можете использовать тег не только, чтобы избежать Java, но и минимизировать ваши HTML-коды. Я сам стараюсь просматривать HTML-коды и создавать теги, как только на моих страницах появляются дубликаты кода.
(Даже если вы в конечном итоге будете использовать java в своем jsp-коде, чего, я надеюсь, нет, вы можете инкапсулировать этот код в тег)
Многие ответы здесь относятся к пути "использовать фреймворк". В этом нет ничего плохого. Однако я не думаю, что это действительно ответ на ваш вопрос, потому что фреймворки могут или не могут использовать JSP, и они не разработаны каким-либо образом с удалением использования java в JSP в качестве основной цели.
Единственный хороший ответ на ваш вопрос "как мне избежать использования Java в JSP": вы не можете.
Вот для чего нужны JSP - использование Java для рендеринга HTML с динамическими данными / логикой. Последующий вопрос может заключаться в том, сколько java я должен использовать в своих JSP.
Прежде чем мы ответим на этот вопрос, вы также должны подумать: "Нужно ли мне использовать JSP для создания веб-контента с помощью Java?" Ответ на последний вопрос - нет. Существует множество альтернатив JSP для разработки веб-приложений с использованием Java. Struts, например, не заставляет вас использовать JSP - не поймите меня неправильно, вы можете использовать их, и многие реализации это делают, но вам это не обязательно. Struts даже не заставляет вас использовать HTML. JSP тоже этого не делает, но давайте будем честными, JSP, не создающий HTML, довольно странно. Как известно, сервлеты позволяют динамически обслуживать любой контент по HTTP. Они первичная технология за довольно много все Java Web - JSPs просто HTML шаблоны для сервлет, на самом деле.
Итак, ответ на вопрос, сколько Java вы должны поместить в JSP, - "как можно меньше". У меня, конечно, есть java в моих JSP, но он состоит исключительно из определений библиотеки тегов, переменных сеанса и клиента, а также bean-компонентов, инкапсулирующих объекты на стороне сервера. Теги <%%> в моем HTML - это почти исключительно вызовы свойств или выражения переменных. Редкие исключения включают сверхспецифические вычисления, относящиеся к одной странице и вряд ли когда-либо будут использоваться повторно; исправления, возникающие из-за проблем со страницей, применимые только к одной странице; конкатенации и арифметические операции в последнюю минуту, вытекающие из необычных требований, ограниченных по объему одной страницей; и другие подобные случаи. В кодовом наборе из 1,5 миллионов строк, 3000 JSP и 5000 классов может быть 100 экземпляров таких уникальных фрагментов.Было бы вполне возможно внести эти изменения в определения классов или библиотек тегов, но это было бы чрезмерно сложным из-за специфики каждого случая, потребовалось бы больше времени для написания и отладки и, в результате, потребовалось бы больше времени, чтобы добраться до моих пользователей. Это призыв к суждению. Но не заблуждайтесь, вы не можете писать JSP любого значения без "java", да и не захотели бы этого. Возможности есть не просто так.
Java сам по себе очень хороший язык, но интенсивное использование в корпоративной среде сделало его стандартные решения чрезвычайно (смехотворно) сложными. Примеры: JSTL, JSF, Wicket и т. д.
Вот суперлегкий подход к созданию бэкенда на Java:
- вообще не используйте JSP (или любой другой механизм шаблонов);
- используйте простые HTML-шаблоны;
- использовать JSOUP для разбора HTML-шаблонов в объект Document;
- изменять объект Document, используя его очень интуитивно понятные методы, подобные jQuery;
- вернуть Document.toString() в качестве ответа на запрос.
Я использую его для одного из своих побочных проектов (размещал дроплет Digitalocean за 5 долларов, Nginx, Tomcat), и он очень быстрый: по данным Googlebot, среднее время отклика составляет около 160 мс.
- Сделайте ваши значения и параметры внутри ваших классов сервлетов
- Получить эти значения и параметры в вашем JSP, используя JSTL/Taglib
Преимущество этого подхода в том, что ваш код также является HTML-подобным кодом!