2010-08-08 3 views
5

Jedną z rzeczy, która zawsze mnie niepokoiła w związku z <jsp:include..> jest to, że nie można przekazywać wartości innych niż String na dołączoną stronę jako odrębne dane wejściowe do strony. Na przykład, chciałbym, aby móc wykonać następujące czynności:Enchanced jsp: include implementation

<c:forEach var="item" items="${listOfItems}"> 
    <jsp:include page="mypage.jsp"> 
     <jsp:attribute name="item" value="${item}/> 
    </jsp:include> 
</c:forEach> 

Pomysł jest, że uznając element jest przekazywana jako atrybut wewnątrz jsp: include węzeł, kod jest jednoznaczne stwierdzenie, jaki był zamiar ... dostarczyć ten parametr do dołączonej strony.

Jedynym obecnie dostępnym mechanizmem jest zdefiniowanie atrybutu "globalnie", a następnie pozwolenie stronie dołączonej na odczytanie go z przestrzeni globalnej. Niestety, traci to ten sam "zamiar", który zapewnia < jsp: param >. Dodatkowo utrudnia kod debugowania, z tego samego powodu, który robią globale w dowolnym środowisku programistycznym.

Czy ktoś wie o implementacji mechanizmu włączania, który wykonuje funkcje jsp: include, ale pozwala przekazywać wartości inne niż String? Lub, jeśli nie, byłbym otwarty na alternatywne pomysły, które zachowałyby ten sam cel intencji i łatwość debugowania.

Na marginesie, chciałbym zobaczyć wbudowane „złapać” mechanizm, gdy włączone strona zgłasza błąd:

<abc:include page="mypage"> 
    <abc:param name="something" value="some string value"/> 
    <abc:attribute name="somethingelse" value="${nonStringValue}"/> 
    <abc:catch var="ex"> 
     The page failed, so the content it generated will not be sent to the output 
     stream. Instead, we can collapse the part of the page that it's content 
     would be... possibly putting a comment in the page with 
     <!-- There was an exception generating this module: 
      <c:out value="${ex.getMessage}/> 
      --> 
    </abc:catch> 
</abc:include> 

Odpowiedz

1

Po przeczytaniu odpowiedzi tutaj, plus robi dodatkowe badania na ten temat, mam wymyślić, co następuje:

  • Można serializacji obiektami następnie deserializować je w dołączonym JSP.Nie jest to fanem tego, ponieważ sprawia, że ​​kod jest bardziej złożony (każdy przekazany obiekt musi być możliwy do serializacji itp.).
  • Możesz użyć taglibs. Nie jestem fanem tego, ponieważ uważam, że pełnią one inną rolę niż pliki JSP obejmują pliki
  • Można zdefiniować zmienne w zakresie żądania, co spowoduje ich udostępnienie na dołączonej stronie JSP. Nie jest wielkim fanem tego, ponieważ nie pokazuje intencji programisty (przekazywanie wartości na dołączoną stronę, tylko w celu jej użycia).
  • Naprawdę nie ma (nie mogłem znaleźć) implementacji, która zapewnia to, czego szukam, ale możliwe jest zbudowanie czegoś, co się zbliża za pomocą niestandardowych tagów.

Zrobiłem trochę pracy i ułożyłem kod, aby osiągnąć to, czego szukałem, a następnie threw it up on sourceforge. To pozwala na określenie wejść w sposób, jaki opisywał:

<inc:include page="normal.jsp"> 
    <inc:param name="param1" value="param1value" /> 
    <inc:param name="param2" value="param2value" /> 
    <inc:attrib name="attrib1" value="${attrib1value}" /> 
    <inc:attrib name="attrib2" value="${attrib2value}" /> 
    <inc:catch var="ex"> 
     This block was not rolled up because there wasn't an error. 
     Should never see this, but just in case, the exception was: ${ex.message} 
    </inc:catch> 
</inc:include> 

Jedyny problem z nim (w tym czasie) jest to, że mogę dodać atrybuty do zakresu żądania zanim strona zostanie włączone, a następnie je usunąć after (lub zresetuj je, jeśli już istniały). Zamiast tego chciałbym zawinąć obiekt żądania i zastąpić metody atrybutu, aby automatycznie uwzględniać wartości przekazane w ... Nadal nad tym pracuję.

+0

Czuję, że źle oznaczam własną odpowiedź jako "odpowiedź", ale naprawdę nie dostałem tego, czego szukałem gdzie indziej. Podano użyteczne informacje, ale musiałem połączyć je i wykorzystać do opracowania własnej implementacji. – RHSeeger

1

allows for passing in non-String values?

Kiedy jesteś ograniczony do przechodzenia Strings wokół, A Typowym rozwiązaniem jest serializacja twoich obiektów.

4

ze specyfikacji JSTL:

Nested scoped variables are only visible within the body of the action and are stored in "page" scope.

można przekazać odwołań do obiektów poprzez życzenie zakres.

standardInclude.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<c:out value="${foo}" /> 

standardAction.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<% 
    //evil scriptlet 
    request.setAttribute("mylist", java.util.Arrays.asList("bar", "baz")); 
%> 
<c:forEach items="${mylist}" var="foo"> 
    <c:set var="foo" scope="request" value="${foo}" /> 
    <jsp:include page="standardInclude.jsp" /> 
    <c:set var="foo" scope="request" value="${null}" /> 
</c:forEach> 

Można użyć tagu catch złapać wyjątki.

thrower.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<c:out value="OK: ${foo}" /> 
<% 
    //evil scriptlet 
    if ("bar".equals(request.getAttribute("foo"))) 
    throw new java.io.IOException("oops"); 
%> 

catcher.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<% 
    //evil scriptlet 
    request.setAttribute("mylist", java.util.Arrays.asList("bar", "baz")); 
%> 
<c:forEach items="${mylist}" var="foo"> 
    <br /> 
    <c:set var="foo" scope="request" value="${foo}" /> 
    <c:catch var="ex"> 
     <jsp:include page="thrower.jsp" /> 
    </c:catch> 
    <c:if test="${ex ne null}"> 
     <c:out value="Error for ${foo}" /> 
    </c:if> 
    <c:set var="foo" scope="request" value="${null}" /> 
</c:forEach> 

To będzie emitować:

Error for bar 
OK: baz 
+0

Chociaż zgadzam się, że zakres żądania przesuwa się częściowo w kierunku "mniejszego zakresu globalnego", nadal udostępnia on zmienną w większym zakresie niż powinien (tj. Bieżący poziom strony zamiast dołączonej strony poziom). Dodatkowo rozwiązuje problem intencji ... nie pokazuje, że konkretnie przekazujesz zmienną na dołączoną stronę. Na haczyku zgadzam się, że to opcja, ale to wszystko jest brzydkie. Cały mechanizm przechwytywania w jsp, choć użyteczny, jest nieco mniejszy niż czysty. – RHSeeger

+0

Po ustawieniu powiązania zasięgu zakresu żądania na wartość null po uwzględnieniu ograniczasz jego widoczność. To, o co prosisz, to rozszerzenie zakresu zmiennej z jednej strony na drugą. Strony JSP definiują skończoną liczbę zakresów: strony, paramu, żądania, sesji i aplikacji. Chyba że chcesz dostać się do 'ThreadLocal's (innej puszki z robakami), to jest tak dobre, jak to tylko możliwe. W przypadku niestandardowej implementacji konieczne byłoby wybranie jednej z tych opcji. Polecam spojrzenie na kod Java wygenerowany przez tłumaczy JSP. Pozwoli ci to lepiej zrozumieć problem, z którym próbujesz się uporać. – McDowell

+0

Co mnie interesuje to zakres, który sprawia, że ​​zmienna jest widoczna dla (gdzie X zawiera Y) w Y, ale nie w X. Jednak chcę, żeby X powiedział "to będzie widoczne w Y", tak jak to robi dla params, gdy zawiera Y. "Wydaje się", że to powinno być możliwe, ponieważ mechanizm włączający musi utworzyć kontekst dla Y (dołączonej strony JSP) do uruchomienia. Problem polega na tym, że "standard" obejmuje-> requestdispatch doesn na to nie zezwalaj. W związku z tym miałem nadzieję, że istnieje niestandardowy znacznik include (przy użyciu niestandardowego RequestDispatcher), który to zrobił. – RHSeeger

0

Można VSD ze znacznika jsp plików zamiast obejmuje. Zobacz moją odpowiedź na podobne pytanie pod numerem JSP Component Creation w celu uzyskania szczegółowych informacji.

+0

Choć prawdą jest, że pliki znaczników mogą przekazywać obiekty jako atrybuty, służą one innym celom niż pliki JSP. Zwłaszcza gdy uwzględnione JSP staje się większe, przeniesienie go do znacznika wydaje się być sprzeczne z pierwotnym celem przekazania intencji programisty. – RHSeeger

+0

@RHSeger, Twój komentarz nie jest dla mnie całkowicie jasny, ale myślę, że w tym pierwszym przykładzie lepszym rozwiązaniem byłby plik z tagami. Używam obejmuje głównie treści statyczne, które są używane na wielu stronach. Z drugiej strony pliki znaczników są użyteczne w przypadku zmiennych treści w zależności od ich parametrów, które są następnie wykorzystywane wielokrotnie na tej samej stronie. –

+0

Zignoruj ​​przykład, który podałem konkretnie, i zakładam, że wołam na stronę JSP i muszę przekazywać rzeczywiste obiekty zamiast ciągów. Stamtąd dołączona strona JSP może zawierać inny plik JSP itp. Plik znaczników, z mojego rozumienia, jest używany bardziej w przypadku małych, modułowych komponentów, które są niezależne. Czy istnieje możliwość bardziej szczegółowego wskazania artykułu/opisu plików znaczników? – RHSeeger