Как избежать Java-кода в файлах JSP?
Я новичок в Java EE, и я знаю, что что-то вроде следующих трех строк
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
- Это старый школьный способ кодирования, и в JSP версии 2 существует метод, чтобы избежать Java-кода в JSP-файлах. Может кто-нибудь, пожалуйста, скажите мне альтернативные линии JSP 2, и как называется эта техника?
29 ответов
использование сценарии (те <% %>
вещи) в JSP действительно очень обескуражен с момента рождения taglibs (типа тегов JSTL) и EL (Язык Выражение те ${}
вещи) еще в 2001.
основные недостатки сценарии являются:
- повторное использование: вы не можете повторно использовать скриптлеты.
- заменяемость: вы не можете сделать сценарии аннотация.
- ОО-способность: вы не можете использовать наследование/композицию.
- Debuggability: если scriptlet бросает исключение наполовину, все, что вы получаете, это пустая страница.
- Контролепригодность: скрипты не поддаются модульной проверке.
- ремонтопригодность: в салдо больше времени необходимо поддерживайте смешанную/загроможденную / дублированную логику кода.
Солнце Oracle сам также рекомендует в соглашения о кодировании JSP чтобы избежать использования сценарии всякий раз, когда та же функциональность возможна классами (тегами). Здесь несколько СИТЕС актуальность:
из спецификации jsp 1.2 настоятельно рекомендуется использовать стандартную библиотеку тегов JSP (JSTL) в вашем веб-приложении, чтобы помочь уменьшить потребность в скриптах JSP на ваших страницах. Страницы, использующие JSTL, в целом легче читать и поддерживать.
...
там, где это возможно, избегайте скриптов JSP всякий раз, когда библиотеки тегов обеспечивают эквивалентную функциональность. Это упрощает чтение и обслуживание страниц ,помогает отделить бизнес-логику от логики презентации и упрощает эволюцию ваших страниц в страницы JSP 2.0 (спецификация JSP 2.0 поддерживает, но deemphasizes использование скриптлетов).
...
в духе принятия шаблона проектирования model-view-controller (MVC) для уменьшения связи между уровнем презентации из бизнес-логики, скрипты JSP не должны использоваться для написания бизнес-логики. Скорее, скриптлеты JSP используются при необходимости для преобразования данных (также называемых "объектами значений"), возвращаемых при обработке запросов клиента, в соответствующий клиент-готовый формат. Даже тогда это было бы лучше сделать с сервлетом переднего контроллера или пользовательским тегом.
как заменить сценарии полностью зависит от единственной цели кода/логики. Более часто этот код должен быть помещен в fullworthy 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. } }
этот путь общаясь с различными назначениями страницы результата легке: redisplaying форма с ошибками валидации в случае ошибки (в этом конкретном примере можно показать с помощью
${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, Весна MVC, калитка и т. д., Чтобы вы получили только страницу 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, код лучше читается (и, следовательно, лучше обслуживается), чем куча скриптов с различными открывающими и закрывающими фигурными скобками (
в качестве гарантии: отключить Скрипты навсегда
As еще вопрос обсуждает, вы можете и всегда должны отключить скрипты в вашем web.xml
дескриптор веб-приложения.
Я всегда буду делать это, чтобы предотвратить добавление скриптов разработчиком, особенно в крупных компаниях, где вы рано или поздно потеряете обзор. The web.xml
настройки выглядят так:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
JSTL предлагает теги для условных обозначений, циклов, наборов, gets и т. д. Например:
<c:if test="${someAttribute == 'something'}">
...
</c:if>
JSTL работает с атрибутами запроса - они чаще всего устанавливаются в запросе сервлетом, который вперед в JSP.
вы можете использовать теги 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>
существуют также компонентные фреймворки, такие как калитка которые генерируют много HTML для вас. Теги, которые заканчиваются в HTML, чрезвычайно просты, и практически нет логики, которая смешивается. В результате получается почти пустые HTML-страницы с типичными HTML-элементами. Недостатком является то, что в калитка API, чтобы учиться, и некоторые вещи могут быть трудно достичь при этих ограничениях.
в архитектурном шаблоне MVC JSPs представляют слой представления. Внедрение java-кода в JSPs считается плохой практикой.
Вы можете использовать JSTL, freeMarker, скорость С JSP в качестве "движка шаблонов".
Поставщик данных для этих тегов зависит от рамки С которым вы имеете дело. Struts 2
и webwork
как реализацию паттерна MVC использует OGNL " очень интересный метод, чтобы подвергнуть свойства бобов JSP ".
опыт показал, что у JSP есть некоторые недостатки, один из которых трудно избежать смешивания разметки с фактическим кодом.
Если вы можете, то рассмотрите возможность использования специализированных технологий для того, что вам нужно сделать. В Java EE 6 есть JSF 2.0, который предоставляет множество приятных функций, включая склеивание Java-бобов вместе со страницами JSF через #{bean.method(argument)}
подход.
калитка также является альтернативой, которая полностью отделяет java от html, поэтому дизайнер и программист могут работать вместе и на разных наборах кода с небольшим пониманием друг друга.
смотреть на калитку.
Если вы просто хотите избежать недостатков 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 зло (исключения времени выполнения, рефакторинг)
Калитка тоже может быть злой (производительность, трудоемкая для небольших приложений или простой уровень просмотра)
Пример java2s,
это должно быть добавлено в веб-приложение.в 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>
вы подняли хороший вопрос, и хотя у вас есть хорошие ответы, я бы предложил вам избавиться от JSP. Это устаревшая технология, которая со временем умрет. Используйте современный подход, например шаблонные движки. У вас будет очень четкое разделение бизнес-и презентационных слоев и, конечно же, нет кода Java в шаблонах, поэтому вы можете создавать шаблоны непосредственно из программного обеспечения для редактирования веб-презентаций, в большинстве случаев используя WYSIWYG.
и, конечно, держаться подальше от фильтров и pre и после обработки, в противном случае вы можете иметь дело с трудностями поддержки/отладки, так как вы всегда не знаете, где переменная получает значение.
чтобы избежать java-кода в JSP-файлах java теперь предоставляет библиотеки тегов, такие как JSTL, также java придумала JSF, в который u может писать все структуры программирования в виде тегов
независимо от того, сколько вы пытаетесь избежать, когда вы работаете с другими разработчиками, некоторые из них все равно предпочитают скриптлет и затем вставить вредоносный код в проект. Поэтому настройка проекта при первом знаке очень важна, если вы действительно хотите уменьшить код скриптлета. Существует несколько методов, чтобы преодолеть это (включая несколько фреймворков, которые упоминались выше). Однако, если вы предпочитаете чистый способ JSP, используйте файл тега JSTL. Хорошая вещь об этом вы можете также настройте главные страницы для своего проекта, чтобы другие страницы могли наследовать главные страницы
создайте главную страницу под названием base.тег под вашим WEB-INF / tags со следующим содержимым
<%@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>
на этой странице mater я создал фрагмент под названием "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>
используется для указания главной страницы, которую вы хотите использовать (которая является базовой.tag в этот момент). Все содержимое внутри тега <jsp:body>
здесь заменит <jsp:doBody/>
на главной странице. Ваша дочерняя страница также может включать любой тег lib, и вы можете использовать его нормально, как и другие упомянутые. Однако, если вы используете какой-либо код скриптлета здесь (<%= request.getParameter("name") %>
...) и попробовать чтобы запустить эту страницу, вы получите JasperException because Scripting elements ( <%!, <jsp:declaration, <%=, <jsp:expression, <%, <jsp:scriptlet ) are disallowed here
. Таким образом, нет никакого способа другие люди могут включить код зла в файл jsp
вызов этой страницы с вашего контроллера:
вы можете легко позвонить ребенку.файл jsp с вашего контроллера. Это также хорошо работает с Struts framework
Если кто-то действительно против программирования на нескольких языках, чем один, Я предлагаю GWT, теоретически вы можете избежать всех элементов JS и HTML, потому что Google Toolkit преобразует весь клиентский и общий код в JS, у вас не будет проблем с ними, поэтому у вас есть веб-сервис без кодирования на любых других языках. Даже вы можете использовать некоторые CSS по умолчанию откуда-то, как это дается расширениями (smartGWT или Vaadin). Вам не нужно изучать десятки аннотаций.
конечно, если вы хотите, вы можете взломать себя в глубины кода и ввести JS и обогатить свою HTML-страницу, но на самом деле вы можете избежать этого, если хотите, и результат будет хорошим, как это было написано в любых других рамках. Я говорю, что уортс пытается, и основной GWT хорошо документирован.
и, конечно, многие программисты описали или рекомендовали несколько других решений. GWT для людей, которые действительно не хотят иметь дело с веб-частью или минимизировать он.
аккуратная идея из мира Python - это языки атрибут шаблона; TAL был введен Zope (поэтому a.к. a. "Шаблоны страниц 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, хотя.
использование скриптов в JSPs не является хорошей практикой.
вместо этого вы можете использовать:
- теги JSTL
- Эль выражения
- пользовательские теги - вы можете определить свои собственные теги, чтобы использовать.
пожалуйста, обратитесь к:
конечно, заменить <%! counter++; %>
по архитектуре производитель-потребитель событий, где бизнес-уровень уведомляется о необходимости увеличения счетчика, он реагирует соответствующим образом и уведомляет докладчиков, чтобы они обновили представления. Задействован ряд транзакций базы данных, так как в будущем нам нужно будет знать новое и старое значение счетчика, кто его увеличил и с какой целью. Очевидно, что сериализация задействована, так как слои полностью развязаны. Вы сможет увеличить ваш счетчик над RMI, IIOP, SOAP. Но требуется только HTML, который вы не реализуете, так как это такой обыденный случай. Ваша новая цель-достичь 250 приращений в секунду на Вашем новом блестящем сервере E7, 64Gb RAM.
У меня более 20 лет в программировании, большинство проектов терпят неудачу до sextet: возможность повторного использования заменяемость OO-способность отладка тестируемость ремонтопригодность даже необходима. Другие проекты, управляемые людьми, которые только заботились функциональность, были чрезвычайно успешными. Кроме того, жесткая структура объекта, реализованная слишком рано в проекте, делает код неспособным адаптироваться к резким изменениям в спецификациях (он же agile).
поэтому я рассматриваю как промедление деятельность по определению "слоев" или избыточных структур данных либо в начале проекта, либо когда это не требуется.
технически, JSP все преобразуются в сервлеты во время выполнения. JSP был первоначально создан с целью развязки бизнес-логики и логики проектирования, следуя шаблону MVC. Таким образом, JSP технически все Java-коды во время выполнения. Но чтобы ответить на вопрос, библиотеки тегов обычно используются для применения логики (удаление Java-кодов) к страницам JSP.
Если мы используем следующие вещи в веб-приложении java, код java может быть исключен с переднего плана JSP.
использовать архитектуру MVC для веб-приложения
-
использовать теги JSP
a. Стандартные Теги
b. Пользовательские Теги
Язык Выражение
Как избежать Java-кода в файлах JSP?
вы можете использовать теги библиотеки вкладок, такие как JSTL в дополнение к языку выражения (EL). Но EL не работает хорошо с JSP. Так что, вероятно, лучше полностью отказаться от JSP и использовать Facelets.
Facelets является первым не JSP язык объявления страницы предназначен для JSF (Java Server Faces) что обеспечило более простое и более мощная модель программирования для разработчиков JSF по сравнению с JSP. Он решает различные проблемы, возникающие в JSP для разработки веб-приложений.
использование скриптов-очень старый способ и не рекомендуется. Если вы хотите напрямую вывести что-то на своих страницах JSP, просто используйте язык выражений (EL) вместе с JSTL .
есть и другие варианты, такие как использование шаблонизатора, таких как скорость, по Freemarker, Thymeleaf и т. д. Но использование простого JSP с EL и JSTL служит моей цели большую часть времени, и это также кажется самым простым для новичка.
кроме того, обратите внимание, что это не рекомендуется выполнять бизнес-логику на уровне представления, следует выполнять бизнес-логику на уровне сервиса, и передайте результат вывода вашим представлениям через контроллер.
ничего из этого больше не используется мой друг, мой совет-отделить представление (css, html, javascript и т. д.) от сервера.
в моем случае я делаю свои системы, обрабатывающие представление с помощью Angular, и любые необходимые данные передаются с сервера с помощью служб rest.
поверьте мне, это изменит то, как вы проектируете
используйте магистраль, угловую, как 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" />
также вы можете прочитать тело тега easly
/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, который имеет много хороших тегов, вы можете обнаружить, что наличие собственных тегов может значительно уменьшить ваш код. Вы можете передать параметры тега в struts и таким образом настроить тег framework.
вы можете использовать тег не только, чтобы избежать java, но и минимизировать HTML-коды. Я сам стараюсь просматривать HTML-коды и создавать теги, как только вижу, что дубликаты кода начинаются на моих страницах.
(даже если вы в конечном итоге используя java в коде jsp, который, я надеюсь, нет, вы можете инкапсулировать этот код в тег)
Как говорят многие ответы, используйте JSTL или создайте свои собственные теги. здесь хорошее объяснение о создании пользовательских тегов
используя теги JSTL вместе с выражением EL, вы можете избежать этого. Поместите следующие вещи на страницу jsp:
<%@ 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" %>