2011-08-23 124 views
12

我有一個使用標籤模板的頁面。 我的web.xml非常基礎。JSP標籤+ scriptlet。如何啓用scriptlet?

我只是想在頁面中運行一些代碼。
不,我對標籤或其他選擇不感興趣。我想使用壞習慣scriptlet哈哈。

到目前爲止,我得到這個 「HTTP錯誤500」 錯誤:

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

雖然我的文件看起來像:

/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> 

我試圖修改web.xml中明確地啓用它,像這樣(沒有工作):所以

<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> 

,我怎麼用我的標籤中的純小腳本」 ed JSP?

編輯#1

理想的代碼是這樣的,使用我的模板( '包裝' 同上)一個頁面內:

<%@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> 

看到了嗎? ''標籤內的&之間的Scriptlets。這正是我想要實現的。

+0

這是在本地版本?您要部署哪個servlet容器?這聽起來像是一個主web.xml不允許這樣做,但需要更多的信息來幫助! – Codemwnci

+0

它在Google App Engine上(它們使用Jetty AFAIK)dev(本地)服務器。 – Poni

回答

16

在這種情況下,容器不關心web.xml中的scripting-invalid的值,因爲它查看jsp:body的標籤元數據,該元數據的主體內容值爲scriptless。所以當你看到:

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

容器抱怨jsp:body的內容,它必須是無腳本的。使用一個scriptlet體標籤,然後使用EL體內像這樣渲染:如果你想呈現小腳本內容在身上,你可以將其設置爲JSP以外的頁面屬性

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

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

嗨喬納森先謝謝你了!其次,整個方法是有限的,並不回答我的問題;如何在這種情況下使用純代碼(無標籤)? – Poni

+1

如果你想完全擺脫所有的標籤,你必須寫一個servlet或者轉換你的JSP來直接調用流寫入器,如下所示:<%out.write(「」); %> –

+1

那麼,我仍然想使用「標籤」,如「」。這只是我想要實現內聯邏輯;使用「if」語句,調用函數和其他任何事情(使用代碼),同時保留在這個「標籤」系統中使用「常規」標籤的能力。爲什麼它必須如此複雜?其實,誰是決定放棄沒有血腥理由限制的聰明男孩? (這些問題不是真的指向你:))。 – Poni

1

我我希望爲這個問題找到一個真正的解決方案,但是我使用的解決方法是創建一箇舊樣式的tld標籤,以保存頁面上下文中的scriptlet片段,然後將其打印到標籤中。

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> 

使用它在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寧願你不需要這樣做 - 但對於那些擁有傳統設計的人來說,這是一個可行的解決方案。好! –

4

簡單地說,如前所述,你不能這樣做。沒有「修復」,它不能完成。標記文件在JSP說法中基本上是「簡單標記」。簡單的標籤就是這樣,簡單的標籤不提供普通JSP標籤的所有選項,包括處理Scriptlets。

所以,他們不限制你能做什麼,而是你不能使用標籤文件來做到這一點。您發現的是,當大多數社區已經避免使用scriptlet時,您似乎都喜歡在JSP中使用scriptlet。

我發現的是,如果我需要訴諸scriptlet代碼,我將代碼包裝到它自己的標記文件中,然後從JSP中調用標記。出於我的目的,這個工作非常好,我只用標記文件(而不是常規的Java)製作了一些非常複雜的標記。

這可能不適合你,因爲我覺得你使用腳本作爲一個規則,而不是一個例外。

0

@Poni

如果你想使用簡單,如果條件我們可以使用下面的小腳本,而不是

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

類末的答案,但這應該工作:

<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

我認爲這是最好的答案。 –

1

根據@bjarnij的回答,我發現這對我來說是最好的解決方案:

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> 

幾乎一樣bjarnij的,但我不得不把c:set外包裝紙。像我一樣的魅力:)