2011-08-23 46 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外包装纸。像我一样的魅力:)