#jsp #jsp-tags
#jsp #jsp-теги
Вопрос:
У меня есть пользовательский тег в файле «.tag», который вычисляет и выводит значение. Поскольку я не могу опубликовать код здесь, давайте рассмотрим простой пример.
Содержимое файла mytag.tag:
<@tag dynamic-attributes="dynamicParameters">
<%@attribute name="key" required="true"%> <%-- this works fine, in spite of dynamic-attributes --%>
<jsp:doBody var="bodyContent/">
<%-- ... here is some code to compute the value of variable "output" --%>
${output}
Вызывающий может легко вызвать его следующим образом:
<prefix:mytag key="foo">Body content...</prefix:mytag>
Это приведет к вставке выходных данных тега. Но я бы также разрешил вызывающей стороне делать что-то вроде этого:
<prefix:mytag key="foo" var="mytagOutput">Body content...</prefix:mytag>
В этом случае вывод фактически не был бы записан, а был бы присвоен переменной «mytagOutput», которую затем может использовать вызывающий.
Я знаю, что вызывающий может достичь этого, обернув пользовательский тег в c:set
, но это менее элегантно, чем простое объявление «var». Я также знаю, что для достижения этой цели можно использовать @variable
директиву с name-from-attribute
. Но тогда я не знаю, был ли атрибут «var» задан вызывающим объектом или нет. (Если задано, я хочу присвоить ${output}
этой переменной, в противном случае я хочу просто записать ${output}
.)
Есть ли способ, как я могу узнать, был ли передан атрибут «var» или нет?
Другим вариантом было бы создать второй пользовательский тег, возможно, называемый «getMytag», который всегда ожидает атрибут «var» и просто оборачивает «mytag» в c:set
. Если я не найду решение здесь, я воспользуюсь этим.
(Если этот вопрос задавался ранее, пожалуйста, укажите мне на него. Я выполнил быстрый поиск, но не нашел похожего вопроса.)
Ответ №1:
Немного поздно, но лучше поздно, чем никогда. Возможно, кому-то еще это покажется полезным
<%@ attribute name="var" required="true" type="java.lang.String" rtexprvalue="false"%>
<%@ attribute name="date" required="true" type="java.sql.Timestamp" description="The date to format"%>
<%@ variable alias="formattedDate" name-from-attribute="var" scope="AT_BEGIN" variable-class="java.lang.String"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="formattedDate">
<fmt:formatDate value="${ date }" pattern="hh:mma " var="time" />
${fn:toLowerCase(time)}<fmt:formatDate value="${ date }" pattern="MMMMM d, y" />
</c:set>
Установите ваш атрибут var (он должен быть обязательным и не допускать rtexprvalue), затем установите псевдоним вашей переменной, который соответствует тому, как вы ссылаетесь на переменную в вашем пользовательском теге.
Вызовите свой пользовательский тег, предоставляющий переменную var
<custom:dateFormat date="${ content.date }" var="formattedDate" />
<c:out value="${formattedDate}" />
Комментарии:
1. это хорошо, и это работает, но ‘var’ является обязательным атрибутом. таким образом, этот тег не сможет ни распечатать свои выходные данные, ни присвоить им значение переменной. он только установит его в переменную.
Ответ №2:
Столкнулся с этой же проблемой и нашел способ решить это без «жестко закодированного» имени переменной, которое должно совпадать между .jsp и .tag.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@
taglib prefix="s" uri="http://www.springframework.org/tags" %>
<jsp:directive.attribute name="someInput" type="java.lang.Object" required="true" rtexprvalue="true" description="Input object" />
<jsp:directive.attribute name="var" type="java.lang.String" required="false" rtexprvalue="false" description="Optional return var name" />
<s:eval expression="@someService.someMethod(someInput)" var="someOutput" />
<c:choose>
<c:when test="${not empty var}">
${pageContext.request.setAttribute(var, someOutput)}
</c:when>
<c:otherwise>
${someOutput}
</c:otherwise>
</c:choose>
Этот тег можно использовать двумя способами:
<%-- Option 1: renders the output of the tag directly to the page --%>
<some:tagname someInput="${yourVar}" />
<%-- Option 2: stores the output of the tag in variable called "result" and lets the caller render the output on his own --%>
<some:tagname someInput="${yourVar}" var="result" />
<c:out value="${result}"/>
Комментарии:
1. Неявный объект PageContext не определен при работе внутри тега. если только taglib Spring каким-то образом не определяет это? но я пробовал это решение без Spring, и оно не сработало.
Ответ №3:
Основываясь на другом ответе, псевдоним переменной кажется отличным обходным путем. Вот простой пример:
<%@ attribute name="urlValue" required="true" type="java.lang.String" %>
<%@ attribute name="var" required="true" type="java.lang.String" rtexprvalue="false" %>
<%@ variable alias="varAlias" name-from-attribute="var" scope="AT_BEGIN" variable-class="java.lang.String"%>
<spring:url value="${urlValue}" var="varAlias"/>