web-dev-qa-db-ja.com

JSPタグ+スクリプトレット。スクリプトレットを有効にする方法は?

タグテンプレートを使用するページがあります。私のweb.xmlは非常に基本的です。

ページでコードを実行したいだけです。
いいえ、タグやその他の代替手段には興味がありません。悪い練習のスクリプトレットを使いたいです。

これまでのところ、この「HTTPERROR500」エラーが発生しています。

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内で純粋なスクリプトレットを使用するにはどうすればよいですか?

編集#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>

見る? ''タグの間および内部のスクリプトレット。それがまさに私が達成しようとしていることです。

13
Poni

この場合、コンテナは、body-content値がscriptlessであるscripting-invalidのタグメタデータを参照するため、web.xmlのjsp:bodyの値を気にしません。だからあなたが見るとき:

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

コンテナは、スクリプトレスでなければならないjsp:bodyの内容について不平を言っています。スクリプトレットのコンテンツを本文でレンダリングする場合は、スクリプトレットを使用してjsp:bodyタグの外側でページ属性として設定し、次のように本文内でELを使用してレンダリングできます。

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

<jsp:body>
${stuff}
</jsp:body>
21
jonathan.cone

ちょっと遅い答えですが、これはうまくいくはずです:

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

簡単に言えば、前述のように、それはできません。それに対する「修正」はありません、それはできません。タグファイルは、基本的にJSP用語では「単純なタグ」です。シンプルタグはまさにそれであり、通常のJSPタグのすべてのオプションを提供するわけではなく、スクリプトレットの処理を含むシンプルなタグです。

したがって、彼らはあなたができることを制約しているのではなく、タグファイルを使ってそれを行うことはできません。あなたが見つけたのは、コミュニティのほとんどがスクリプトレットを避けているときに、JSPでスクリプトレットを使用することを楽しんでいるように見える数少ない人の1人であるということです。

私が見つけたのは、スクリプトレットコードに頼る必要がある場合は、そのコードを独自のタグファイルに入れてから、JSPからタグを呼び出すことです。私の目的では、これは非常にうまく機能しており、(従来のJavaではなく)タグファイルのみを使用して非常に洗練されたタグを作成しました。

例外としてではなく、原則としてスクリプトレットを使用しているように感じるので、これはおそらく機能しません。

4
Will Hartung

@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を配置する必要がありました。私にとっては魅力のように機能します:)

2
Hans Araya

この問題の実際の解決策を探していますが、使用している回避策は、古いスタイルのtldタグを作成して、スクリプトレットフラグメントをページコンテキストに保存し、タグ内に出力することです。

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>
1
Ali Shakiba

以下は、JSPXページでのコーディングのようなスクリプトを追加するために使用したコードです。

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>

注:<jsp:declaration>,</jsp:declaration><jsp:expression><![CDATA[... ]]>と適切に組み合わせるとうまくいきます。

以下は参照リンクです。

0

@ポニー

単純なif条件を使用する場合は、スクリプトレットの代わりに次を使用できます

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