Примечание: мне трудно придумать какие-либо скрытые функции для JSP / Servlet. На мой взгляд, лучшие практики - это лучшая формулировка, и я могу вспомнить любую из них. Это также действительно зависит от вашего опыта работы с JSP / Servlet. Спустя годы разработки вы больше не видите этих скрытых функций. В любом случае, я перечислю некоторые из тех небольших передовых практик, о которых я за долгие годы обнаружил, что многие начинающие не полностью осведомлены об этом. Это было бы классифицировано как скрытые особенности в глазах многих начинающих. Во всяком случае, вот список :)
Скрыть страницы JSP от прямого доступа
Помещая файлы JSP в папку /WEB-INF
, вы эффективно скрываете их от прямого доступа, например, http://example.com/contextname/WEB-INF/page.jsp
. Это приведет к 404
. После этого вы сможете получить к ним доступ только с помощью RequestDispatcher
в сервлете. или используя jsp:include
.
Предварительный запрос для JSP
Большинство знает о _ 6_ для публикации - обработки запроса (отправки формы), но большинство из них не знают, что вы можете использовать doGet()
, чтобы предварительно обработать запрос JSP. Например:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Item> items = itemDAO.list();
request.setAttribute("items", items);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
}
который используется для предварительной загрузки некоторых табличных данных, которые должны отображаться с помощью JSTL c:forEach
:
<table>
<c:forEach items="${items}" var="item">
<tr><td>${item.id}</td><td>${item.name}</td></tr>
</c:forEach>
</table>
Сопоставьте такой сервлет с url-pattern
из /page
(или /page/*
) и просто вызовите http://example.com/contextname/page
с помощью адресной строки браузера или простой ванильной ссылки для его запуска. См. Также, например, doGet и doPost в сервлетах.
Динамический включает
Вы можете использовать EL в jsp:include
:
<jsp:include page="/WEB-INF/${bean.page}.jsp" />
bean.getPage()
может просто вернуть действительное имя страницы.
EL может получить доступ к любому получателю
EL сам по себе не требует, чтобы объект, к которому должен быть осуществлен доступ, был полноценным Javabean. Наличие метода no-arg с префиксом get
или is
более чем достаточно для доступа к нему в EL. Например.:
${bean['class'].name}
Это возвращает значение _21 _ где метод getClass()
фактически унаследован от Object#getClass()
. Обратите внимание, что class
указывается в скобках []
по причинам, указанным здесь instanceof check in Язык выражения EL.
${pageContext.session.id}
Это возвращает значение _27 _ что полезно в ао Может ли апплет взаимодействовать с экземпляром сервлета а>.
${pageContext.request.contextPath}
Это возвращает значение _29 _ что полезно в ао Как использовать относительные пути без включения корня контекста имя?
EL также может получить доступ к картам
Следующие обозначения EL
${bean.map.foo}
разрешается в bean.getMap().get("foo")
. Если ключ Map
содержит точку, вы можете использовать нотацию скобок []
с ключом в кавычках:
${bean.map['foo.bar']}
который разрешается в bean.getMap().get("foo.bar")
. Если вам нужен динамический ключ, используйте также фигурные скобки, но без кавычек:
${bean.map[otherbean.key]}
который разрешается в bean.getMap().get(otherbean.getKey())
.
Итерировать по карте с помощью JSTL
Вы также можете использовать c:forEach
для перебирать Map
. Каждая итерация дает Map.Entry
, который в Turn имеет методы getKey()
и getValue()
(так что вы можете просто получить к нему доступ в EL с помощью ${entry.key}
и ${entry.value}
). Пример:
<c:forEach items="${bean.map}" var="entry">
Key: ${entry.key}, Value: ${entry.value} <br>
</c:forEach>
См. Также, например, Отладка с помощью jstl - как именно?
Получить текущую дату в JSP
Вы можете получить текущую дату с помощью jsp:useBean
и отформатировать ее с помощью JSTL. fmt:formatDate
<jsp:useBean id="date" class="java.util.Date" />
...
<p>Copyright © <fmt:formatDate value="${date}" pattern="yyyy" /></p>
Это печатается (на данный момент) следующим образом: Copyright © 2010.
Легко понятные URL-адреса
Простой способ создать удобный URL-адрес - использовать _ 49_ и JSP скрыты в /WEB-INF
:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response);
}
Если вы отобразите этот сервлет, например, на /pages/*
, тогда запрос на http://example.com/contextname/pages/foo/bar
будет эффективно отображать /WEB-INF/foo/bar.jsp
. Вы можете сделать еще один шаг, разделив pathinfo на /
и выбрав только первую часть как URL-адрес страницы JSP, а остаток как бизнес-действия (пусть сервлет действует как контроллер страницы). См. Также, например, веб-приложений шаблонов проектирования.
Повторно отображать вводимые пользователем данные с помощью ${param}
Неявный объект EL ${param}
, который ссылается на HttpServletRequest#getParameterMap()
можно использовать для повторного отображения введенных пользователем данных после отправки формы в JSP:
<input type="text" name="foo" value="${param.foo}">
В основном это то же самое, что и request.getParameterMap().get("foo")
. См. Также, например, Как можно Я сохраняю значения полей формы HTML в JSP после отправки формы сервлету?
Не забудьте предотвратить XSS! См. Следующую главу.
JSTL для предотвращения XSS
Чтобы предотвратить использование вашего сайта XSS, все, что вам нужно сделать, это (повторно) отобразить < надежные> контролируемые пользователем данные с использованием JSTL _ 61_ или c:out
< / а>.
<p><input type="text" name="foo" value="${fn:escapeXml(param.foo)}">
<p><c:out value="${bean.userdata}" />
Чередование <table>
строк с LoopTagStatus
Атрибут varStatus
в JSTL c:forEach
дает вы LoopTagStatus
, вернувшийся в свою очередь, имеет несколько методов получения (которые можно использовать в EL!). Итак, чтобы проверить четность строк, просто проверьте loop.getIndex() % 2 == 0
:
<table>
<c:forEach items="${items}" var="item" varStatus="loop">
<tr class="${loop.index % 2 == 0 ? 'even' : 'odd'}">...</tr>
<c:forEach>
</table>
который фактически закончится
<table>
<tr class="even">...</tr>
<tr class="odd">...</tr>
<tr class="even">...</tr>
<tr class="odd">...</tr>
...
</table>
Используйте CSS, чтобы задать им другой цвет фона.
tr.even { background: #eee; }
tr.odd { background: #ddd; }
Заполните строку с разделителями-запятыми из списка / массива с помощью LoopTagStatus
:
Еще один полезный метод LoopTagStatus
- _75 _:
<c:forEach items="${items}" var="item" varStatus="loop">
${item}${!loop.last ? ', ' : ''}
<c:forEach>
В результате получается что-то вроде item1, item2, item3
.
EL функции
Вы можете объявить public static
служебные методы как функции EL (например, как JSTL functions), чтобы вы могли использовать их в EL. Например.
package com.example;
public final class Functions {
private Functions() {}
public static boolean matches(String string, String pattern) {
return string.matches(pattern);
}
}
с /WEB-INF/functions.tld
, которые выглядят следующим образом:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>Custom_Functions</short-name>
<uri>http://example.com/functions</uri>
<function>
<name>matches</name>
<function-class>com.example.Functions</function-class>
<function-signature>boolean matches(java.lang.String, java.lang.String)</function-signature>
</function>
</taglib>
который можно использовать как
<%@taglib uri="http://example.com/functions" prefix="f" %>
<c:if test="${f:matches(bean.value, '^foo.*')}">
...
</c:if>
Получить исходный URL-адрес запроса и строку запроса
Если JSP был перенаправлен, вы можете получить исходный URL-адрес запроса,
${requestScope['javax.servlet.forward.request_uri']}
и исходную строку запроса запроса,
${requestScope['javax.servlet.forward.query_string']}
Вот и все. Может, рано или поздно я добавлю еще.
person
Community
schedule
26.03.2010