2011-08-23 9 views
12

Mam stronę, która używa szablonu znacznika. Mój web.xml jest bardzo prosty.Znaczniki JSP + skryptlet. Jak włączyć skryptlet?

Po prostu chcę uruchomić jakiś kod na stronie.
I nie, nie jestem zainteresowany tagami ani innymi alternatywami. Chcę użyć skryptu z haherami.

tej pory dostaję to "Błąd HTTP 500" Błąd:

Scripting elements (%!, jsp:declaration, %=, jsp:expression, %, jsp:scriptlet) are disallowed here. 

Choć moje pliki wyglądać następująco:

/WEB-INF/web.xml

<?xml version="1.0" encoding="utf-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    version="2.5"> 

    <welcome-file-list> 
     <welcome-file>index.html</welcome-file> 
     <welcome-file>index.jsp</welcome-file> 
    </welcome-file-list> 
</web-app> 

/WEB-INF/tags/wrapper.tag

<%@tag description="Simple Wrapper Tag" pageEncoding="UTF-8"%> 
<%@ attribute name="title" required="true" type="java.lang.String"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

<html> 
<head> 
<title>${title}</title> 
</head> 

<body> 
    <jsp:doBody /> 
</body> 
</html> 

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<%@taglib prefix="t" tagdir="/WEB-INF/tags"%> 

<t:wrapper> 
    <jsp:attribute name="title">My nice title</jsp:attribute> 

    <jsp:body> 
    <h1><%="some code generated text"%></h1> 
    </jsp:body> 
</t:wrapper> 

Próbowałem zmodyfikować web.xml jawnie go włączyć, jak to (nie działa):

<jsp-config> 
    <jsp-property-group> 
     <url-pattern>*.jsp</url-pattern> 
     <scripting-invalid>false</scripting-invalid> 
    </jsp-property-group> 
    <jsp-property-group> 
     <url-pattern>*.tag</url-pattern>     
     <scripting-invalid>false</scripting-invalid> 
    </jsp-property-group> 
</jsp-config> 

Tak, jak mogę używać czystych scriptlets w moim tagu” ed JSP?

EDIT # 1:

Idealnym kod wyglądałby następująco, w środku strony, która korzysta z mojego szablonu ('wrapper', jak wyżej):

<%@page import="java.util.Calendar"%> 
<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<%@taglib prefix="t" tagdir="/WEB-INF/tags"%> 

<t:wrapper> 
    <jsp:attribute name="title">My nice title</jsp:attribute> 

    <% 
     final int day_of_week = Calendar.getInstance().get(
       Calendar.DAY_OF_WEEK); 
     if (day_of_week == Calendar.SATURDAY) 
     { 
    %> 
    <jsp:body> 
    <h1>Have a nice Saturday (<%=Integer.toString(day_of_week)%>)!</h1> 
    </jsp:body> 
    <% 
     } 
     else 
     { 
    %> 
    <jsp:body> 
    <h1>Have a nice rest-of-the-week (<%=Integer.toString(day_of_week)%>)!</h1> 
    </jsp:body> 
    <% 
     } 
    %> 
</t:wrapper> 

zobaczyć? Skrypty między & wewnątrz tagów "". Dokładnie to próbuję osiągnąć.

+0

czy jest to wersja lokalna? Do jakiego kontenera serwletu się używasz? Wygląda na to, że jest to master web.xml, ale tego potrzebujesz, ale potrzebujesz więcej informacji! – Codemwnci

+0

Jest on na Google App Engine (używają Jetty AFAIK) dev (lokalny) serwer. – Poni

Odpowiedz

16

W tym przypadku, pojemnik nie dba o wartości scripting-invalid w web.xml, ponieważ jej spojrzenie na tagu meta-danych dla jsp:body który ma wartość ciała, zawartości scriptless. Więc gdy widzisz:

Scripting elements (%!, jsp:declaration, %=, jsp:expression, %, jsp:scriptlet) are disallowed here. 

Kontener skarży się na zawartość jsp: body, która musi być bez skryptów. Jeśli chcesz uczynić skrypty zawartości w organizmie, można ustawić go jako atrybut widoku zewnętrznym z jsp: tag ciała za pomocą scriptlet a następnie uczynić go przy użyciu EL wewnątrz ciała tak:

<% request.setAttribute("stuff", object); %> 

<jsp:body> 
${stuff} 
</jsp:body> 
+1

Cześć Jonathan, dziękuję, to jest pierwsze! Po drugie, całe podejście ogranicza się i nie odpowiada na moje pytanie; Jak korzystać z czystego kodu (bez żadnych tagów) w tej sytuacji? – Poni

+1

Jeśli chcesz całkowicie pozbyć się wszystkich znaczników, musisz albo napisać serwlet, albo przekonwertować stronę JSP, aby wywołać program zapisujący strumienie bezpośrednio: <% out.write (""); %> –

+1

Cóż, nadal chcę używać "tagów", takich jak "". Chodzi o to, że chcę zaimplementować logikę inline; używaj instrukcji "if", wywołuj funkcje i cokolwiek innego (z kodem), zachowując przy tym możliwość używania "zwykłych" tagów w tym systemie "tagów". Dlaczego do cholery to musi być tak skomplikowane? Właściwie to kto jest sprytnym chłopcem, który zdecydował się na wprowadzenie limitu bez żadnego krwawego powodu? (pytania nie są skierowane do Ciebie naprawdę :)). – Poni

1

I Zamierzam znaleźć prawdziwe rozwiązanie tego problemu, ale obejście, którego używam, polega na utworzeniu starego znacznika tld do zapisania fragmentu skryptu w kontekście strony, a następnie wydrukowania go wewnątrz znacznika.

public class PushTag extends BodyTagSupport { 
    private String key; 
    public int doStartTag() throws JspException { 
     return EVAL_BODY_BUFFERED; 
    } 
    @Override 
    public int doAfterBody() throws JspException { 
     pageContext.setAttribute(PREFIX + key, getBodyContent().getString()); 
     return SKIP_BODY; 
    } 
    public String getKey() { 
     return key; 
    } 
    public void setKey(String key) { 
     this.key = key; 
    } 
    private static final String PREFIX = PushTag.class.getPackage().getName() 
      + "."; 
    private static final long serialVersionUID = 1L; 
} 

public class PopTag extends BodyTagSupport { 
    private String key; 
    @Override 
    public int doStartTag() throws JspException { 
     try { 
      String bc = (String) pageContext.getAttribute(PREFIX + key); 
      if (bc != null) { 
       pageContext.getOut().write(bc); 
      } 
     } catch (Exception e) { 
      throw new JspException("Error:" + e.getMessage()); 
     } 
     return super.doStartTag(); 
    } 
    public String getKey() { 
     return key; 
    } 
    public void setKey(String key) { 
     this.key = key; 
    } 
    private static final String PREFIX = PopTag.class.getPackage().getName() 
      + "."; 
    private static final long serialVersionUID = 1L; 
} 

pushpop.tld

<taglib> 
    <tlib-version>1.2</tlib-version> 
    <jsp-version>2.1</jsp-version> 
    <short-name>q</short-name> 
    <uri>http://dev.example.com/jsp/taglib/</uri> 
    <tag> 
     <name>push</name> 
     <tag-class>x.web.PushTag</tag-class> 
     <body-content>JSP</body-content> 
     <attribute> 
      <name>key</name> 
      <required>true</required> 
      <type>java.lang.String</type> 
     </attribute> 
    </tag> 
    <tag> 
     <name>pop</name> 
     <tag-class>x.web.PopTag</tag-class> 
     <body-content>JSP</body-content> 
     <attribute> 
      <name>key</name> 
      <required>true</required> 
      <type>java.lang.String</type> 
     </attribute> 
    </tag> 
</taglib> 

Użyj go w jsp:

<%@ taglib prefix="x" uri="http://example.com/jsp/taglib/" %> 

<x:push key="scriptful"><%= "We Love SCRIPTLETS!" %></x:push> 

<t:wrapper><x:pop key="scriptful"/></t:wrapper> 
+0

JSP 2 wolałby, żebyś tego nie musiał robić - ale realnym rozwiązaniem dla osób ze starszymi projektami. Dobry! –

4

Po prostu, jak już wspomniano, nie można tego zrobić. Nie ma na to "poprawki", nie da się tego zrobić.Pliki znaczników to w zasadzie "proste znaczniki" w języku JSP. Prostymi tagami są właśnie te prostsze tagi, które nie oferują wszystkich opcji normalnego znacznika JSP, a także obejmowały obsługę skryptletów.

Nie ograniczają one tego, co można zrobić, ale nie można w tym celu użyć plików znaczników. Zauważyłeś, że jesteś jednym z niewielu, którzy zdają się czerpać przyjemność z używania skryptletów w JSP, gdy większość społeczności ich unika.

To, co odkryłem, to że jeśli potrzebuję uciekać się do kodu skryptu, umieszczam ten kod w jego własnym pliku znaczników, a następnie wywołuję tag ze strony JSP. Dla moich celów to zadziałało całkiem dobrze i stworzyłem całkiem wyrafinowane tagi używając tylko plików znaczników (zamiast konwencjonalnej Javy).

To prawdopodobnie nie będzie działać dla ciebie, ponieważ mam wrażenie, że używasz skryptletów z reguły, a nie jako wyjątek.

0

@Poni

Jeśli chcesz użyć proste, jeśli warunek możemy użyć następującego zamiast scriptlet

<c:if test="${!empty flashMsg}"> 
    <p>your content</p> 
</c:if> 
5

trochę późno odpowiedź, ale to powinno działać:

<t:wrapper> 
    <jsp:attribute name="title">My nice title</jsp:attribute> 
    <c:set var="bodyContent"> 
     <% 
      final int day_of_week = Calendar.getInstance().get(Calendar.DAY_OF_WEEK); 
      if (day_of_week == Calendar.SATURDAY) 
      { 
     %> 
     <h1>Have a nice Saturday (<%=Integer.toString(day_of_week)%>)!</h1> 
     <% 
      } 
      else 
      { 
     %> 
     <jsp:body> 
     <h1>Have a nice rest-of-the-week (<%=Integer.toString(day_of_week)%>)!</h1> 
     </jsp:body> 
     <% 
      } 
     %> 
    </c:set> 
    <jsp:body> 
     ${bodyContent} 
    </jsp:body> 
</t:wrapper> 
+0

Myślę, że to najlepsza odpowiedź. –

1

Na podstawie odpowiedzi @ bjarnij, uznałem to za najlepsze rozwiązanie dla mnie:

myJSP.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> 

<c:set var="bodyContent"> 
    <% 
     //Your content with scriplets and everything 
    %> 
</c:set> 

<t:wrapper> 
    <jsp:body> 
     ${bodyContent} 
    </jsp:body> 
</t:wrapper> 

Prawie taka sama jak bjarnij-tych, ale musiałem c:set zewnętrzną owijkę. Działa jak urok dla mnie :)