【问题标题】:JSP tags + scriptlet. How to enable scriptlet?JSP 标签 + scriptlet。如何启用脚本?
【发布时间】:2011-11-02 04:52:34
【问题描述】:

我有一个使用标签模板的页面。 我的 web.xml 非常基础。

我只是想在页面中运行一些代码。
不,我对标签或其他替代方案不感兴趣。我想用坏习惯的scriptlet哈哈。

到目前为止,我收到了这个“HTTP ERROR 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>

那么,如何在我的标记 JSP 中使用纯 scriptlet?

编辑#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>

看到了吗? '' 标签内 & 之间的 Scriptlet。这正是我想要实现的目标。

【问题讨论】:

  • 这是本地版本吗?您要部署到哪个 servlet 容器?听起来这是一个主 web.xml 不允许这样做,但需要更多信息来帮助!
  • 它在 Google App Engine(他们使用 Jetty AFAIK)开发(本地)服务器上。

标签: java jsp jsp-tags scriptlet


【解决方案1】:

在这种情况下,容器不关心 web.xml 中 scripting-invalid 的值,因为它查看 jsp:body 的标记元数据,它的 body-content 值为 scriptless。所以当你看到:

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

容器抱怨 jsp:body 的内容必须是无脚本的。如果要在正文中呈现 scriptlet 内容,可以使用 scriptlet 将其设置为 jsp:body 标记之外的页面属性,然后在正文中使用 EL 将其呈现,如下所示:

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

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

【讨论】:

  • 嗨乔纳森谢谢你这是第一个!其次,整个方法是有限的,没有回答我的问题;在这种情况下如何使用纯代码(没有任何标签)?
  • 如果你想完全摆脱所有标签,你要么必须编写一个 servlet,要么转换你的 JSP 来直接调用流编写器,如下所示: "); %>
  • 好吧,我还是想使用像“”这样的“标签”。只是我想实现内联逻辑;使用“if”语句、调用函数并实际执行任何其他操作(使用代码),同时保留在此“标签”系统中使用“常规”标签的能力。为什么它必须如此复杂?实际上,谁是无缘无故决定限制的聪明男孩? (这些问题并没有真正指向你:))。
  • 这是进化的结果。人们意识到 scriptlet 会导致页面无法维护,因此当 JSP 2.0 出来并引入标签文件时,他们说“它必须停止”,而强制执行的方法之一是不让您将 scriptlet 内容添加到标签文件标签由 jsp:body 定义的主体。对不起。 :)
  • 是的,当有人强迫你以某种方式编码,没有“真正的”原因(如语言设计问题等)时,这真的很糟糕。事实上,我可以在 JSP 中编写一个 scriptlet....但是当它在“jsp:body”中时它是错误的.. ffff.. 这些家伙.. 所以你不知道如何让它工作呃?希望有人会听到这个问题,并回答..还是谢谢!
【解决方案2】:

有点晚的答案,但这应该可行:

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

【讨论】:

  • 我认为这是最好的答案。
【解决方案3】:

简单地说,如上所述,您不能这样做。它没有“修复”,它无法完成。标记文件基本上是 JSP 用语中的“简单标记”。简单标记就是这样,更简单的标记不提供普通 JSP 标记的所有选项,并且包括处理 Scriptlet。

因此,它们并没有限制您可以做什么,而是您不能使用标记文件来执行此操作。您发现,您是少数似乎喜欢在 JSP 中使用 scriptlet 的人之一,而大多数社区都避免使用它们。

我发现,如果我需要使用 scriptlet 代码,我会将该代码封装到它自己的标记文件中,然后从 JSP 调用该标记。就我的目的而言,这非常有效,而且我只使用标签文件(而不是传统的 Java)制作了一些非常复杂的标签。

这可能对您不起作用,因为我觉得您通常使用 scriptlet,而不是作为例外。

【讨论】:

    【解决方案4】:

    根据@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 放在包装器之外。对我来说就像一个魅力:)

    【讨论】:

      【解决方案5】:

      我正在寻找一个真正解决这个问题的方法,但我正在使用的解决方法是创建一个旧式 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>
      

      【讨论】:

      • JSP 2 更希望您不需要这样做——但对于那些具有遗留设计的人来说,这是一个可行的解决方案。好!
      【解决方案6】:

      @Poni

      如果你想使用简单的 if 条件,我们可以使用下面的来代替 scriptlet

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

      【讨论】:

        【解决方案7】:

        下面是我用来在 JSPX 页面中添加类似 scriplet 的代码。

        在编辑 Spring-Roo 创建的模板页面时,代码也可以工作。

        <?xml version="1.0" encoding="UTF-8" standalone="no"?>
        <div xmlns:c="http://java.sun.com/jsp/jstl/core"
            xmlns:fn="http://java.sun.com/jsp/jstl/functions"
            xmlns:jsp="http://java.sun.com/JSP/Page"
            xmlns:spring="http://www.springframework.org/tags"
            xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" id="footer" version="2.0">
            <jsp:directive.page contentType="text/html;charset=UTF-8" />
            <jsp:output omit-xml-declaration="yes" />
        
        
            <jsp:declaration> String t; </jsp:declaration>
            <jsp:scriptlet> 
            <![CDATA[
                t="Declared and Initialized From Scriplet";
            ]]>
            </jsp:scriptlet>
        
        
            <jsp:scriptlet> 
            <![CDATA[
            for(int i=0;i<3;i++){
            ]]>
            </jsp:scriptlet>
                    <jsp:expression>t+i</jsp:expression> <![CDATA[ iteration &nbsp;&nbsp;<br/>]]>
            <jsp:scriptlet> 
            <![CDATA[
            }
            ]]>
            </jsp:scriptlet>
        </div>
        

        注意:&lt;jsp:declaration&gt;,&lt;/jsp:declaration&gt;&lt;jsp:expression&gt;&lt;![CDATA[... ]]&gt; 的正确组合可以解决问题。

        以下是参考链接:

        【讨论】:

          猜你喜欢
          • 2016-01-03
          • 2010-10-18
          • 2011-11-09
          • 1970-01-01
          • 2013-09-01
          • 2012-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多