web-dev-qa-db-fra.com

Balises JSP + scriptlet. Comment activer le scriptlet?

J'ai une page qui utilise un modèle de balise. Mon web.xml est très basique.

Je veux simplement exécuter du code dans la page.
Et non, je ne suis pas intéressé par les balises ou autres alternatives. Je veux utiliser le scriptlet mauvaise pratique haha.

Jusqu'ici, j'obtiens l'erreur "HTTP ERROR 500":

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

Alors que mes fichiers ressemblent à:

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

J'ai essayé de modifier web.xml pour l'activer explicitement, comme ceci (ne fonctionne pas):

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

Alors, comment utiliser des scriptlets purs dans mon JSP étiqueté?

EDIT # 1 :

Un code idéal ressemblerait à ceci , dans une page qui utilise mon modèle ('wrapper' comme ci-dessus):

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

Voir? Des scriptlets entre et dans les balises ''. C'est exactement ce que j'essaie de réaliser.

13
Poni

Dans ce cas, le conteneur ne se soucie pas de la valeur de scripting-invalid dans web.xml, car il examine les métadonnées de balise pour jsp:body qui a une valeur de corps de contenu de scriptless. Alors quand tu vois:

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

Le conteneur se plaint du contenu de jsp: body qui doit être sans script. Si vous souhaitez rendre le contenu de scriptlet dans le corps, vous pouvez le définir comme attribut de page en dehors de la balise jsp: body à l'aide d'un scriptlet, puis le restituer à l'aide de EL à l'intérieur du corps, comme suit:

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

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

Type de réponse tardive, mais cela devrait marcher:

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

En termes simples, comme mentionné, vous ne pouvez pas faire cela. Il n'y a pas de "solution" à cela, cela ne peut pas être fait. Les fichiers de balises sont essentiellement des "balises simples" au sens de JSP. Les balises simples ne sont que cela, des balises plus simples qui n'offrent pas toutes les options d'une balise JSP normale et qui incluent la gestion des scriptlets.

Donc, ils ne limitent pas ce que vous pouvez faire, mais vous ne pouvez pas utiliser de fichiers de balises pour le faire. Ce que vous avez découvert, c’est que vous êtes l’un des rares qui semble apprécier l’utilisation des scriptlets dans JSP alors que la plupart des membres de la communauté les ont évités.

Ce que j'ai trouvé, c'est que si je dois recourir au code de scriptlet, je l'enveloppe dans son propre fichier de balise, puis j'appelle la balise à partir du fichier JSP. Cela a très bien fonctionné pour mes besoins et j'ai créé des balises assez sophistiquées en utilisant uniquement des fichiers de balises (plutôt qu'en Java conventionnel).

Cela ne fonctionnera probablement pas pour vous, car j'ai l'impression que vous utilisez les scriptlets en règle plutôt qu'en tant qu'exception.

4
Will Hartung

Basé sur la réponse de @bjarnij, j'ai trouvé que c'était la meilleure solution pour moi:

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>

Presque identique à celui de bjarnij, mais je devais mettre c:set en dehors de l'emballage. Fonctionne comme un charme pour moi :)

2
Hans Araya

Je cherche une solution réelle à ce problème, mais la solution que j'utilise est la création d'une balise tld de style ancien pour enregistrer le fragment de scriptlet dans le contexte de la page, puis l'imprimer dans une balise.

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>

Utilisez-le dans 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

Vous trouverez ci-dessous le code que j’utilisais pour ajouter scriplet, comme dans les pages JSPX.

Le code fonctionne également lors de l'édition de modèles de pages créées par 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>

Remarque: La combinaison correcte de <jsp:declaration>,</jsp:declaration> et <jsp:expression> avec <![CDATA[... ]]> fait l'affaire.

Voici des liens de référence:

0
Charudatta Joshi

@ Poni

Si vous voulez utiliser la condition simple if, nous pouvons utiliser les éléments suivants au lieu de scriptlet

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