Теги JSP + скриптлет. Как включить скриптлет?

У меня есть страница, которая использует шаблон тега. Мой web.xml очень простой.

Я просто хочу запустить некоторый код на странице.
И нет, меня не интересуют теги или другие альтернативы. Я хочу использовать сценарий плохой практики, ха-ха.

Пока я получаю эту ошибку «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 с тегами?

РЕДАКТИРОВАНИЕ №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>

Видеть? Скриптлеты между и внутри тегов ''. Это именно то, чего я пытаюсь достичь.


person Poni    schedule 23.08.2011    source источник
comment
это в локальной версии? Какой контейнер сервлетов вы развертываете? Похоже, что мастер web.xml запрещает это, но нужна дополнительная информация, чтобы помочь!   -  person Codemwnci    schedule 23.08.2011
comment
Это на сервере Google App Engine (они используют Jetty AFAIK) dev (local).   -  person Poni    schedule 23.08.2011


Ответы (7)


В этом случае контейнеру не важно значение scripting-invalid в файле web.xml, потому что он просматривает метаданные тега для jsp:body, значение основного содержимого которого равно scriptless. Итак, когда вы видите:

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>
person jonathan.cone    schedule 23.08.2011
comment
Привет, Джонатан, спасибо, это первое! Во-вторых, весь подход ограничивает и не отвечает на мой вопрос; Как мне использовать чистый код (без тегов вообще) в этой ситуации? - person Poni; 24.08.2011
comment
Если вы хотите полностью избавиться от всех тегов, вам придется либо написать сервлет, либо преобразовать JSP для прямого вызова средства записи потока, например: ‹% out.write(‹html›); %› - person jonathan.cone; 24.08.2011
comment
Что ж, я все еще хочу использовать такие теги, как '‹jsp:body›'. Просто я хочу реализовать встроенную логику; использовать операторы if, вызывать функции и делать что-либо еще (с кодом) на самом деле, сохраняя при этом возможность использования обычных тегов в этой системе тегов. Почему, черт возьми, это должно быть так сложно? На самом деле, кто тот умный мальчик, который решил поставить лимит ни с того ни с сего? (вопросы не адресованы вам на самом деле :) ). - person Poni; 24.08.2011
comment
Это результат эволюции. Люди поняли, что скриптлеты приводят к невозможности сопровождения страниц, поэтому, когда вышел JSP 2.0 и были введены файлы тегов, они сказали, что это должно быть остановлено, и один из способов, которым это обеспечивается, — запретить вам добавлять содержимое скриптлета в тела тегов файлов тегов, определенные по jsp:тело. Прости. :) - person jonathan.cone; 24.08.2011
comment
Да, это действительно отстой, когда кто-то заставляет вас кодировать определенным образом без какой-либо реальной причины (например, проблемы с дизайном языка и т. Д.). Это факт, что я могу написать скриптлет в JSP.... но когда он в jsp:body, это неправильно.. ffff.. Эти ребята.. Значит, вы не знаете, как заставить его работать, а? Надеюсь, кто-нибудь услышит об этом вопросе и ответит... в любом случае спасибо!! - person Poni; 24.08.2011

Вид позднего ответа, но это должно работать:

<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>
person bjarnij    schedule 16.12.2013
comment
Я думаю, что это лучший ответ. - person Serhii Maksymchuk; 27.09.2016

Проще говоря, как уже упоминалось, вы не можете этого сделать. Нет никакого "исправления" к этому, это не может быть сделано. Файлы тегов в основном являются «простыми тегами» на языке JSP. Простые теги — это просто теги Simpler, которые не предлагают всех параметров обычного тега JSP, включая обработку скриптлетов.

Таким образом, они не ограничивают то, что вы можете делать, скорее, вы не можете использовать для этого файлы тегов. Вы обнаружили, что вы один из немногих, кому нравится использовать скриптлеты в JSP, в то время как большая часть сообщества их избегает.

Я обнаружил, что если мне нужно прибегнуть к коду скриптлета, я заключаю этот код в его собственный файл тегов, а затем вызываю тег из JSP. Для моих целей это сработало достаточно хорошо, и я создал довольно сложные теги, используя только файлы тегов (а не обычный Java).

Это, вероятно, не сработает для вас, так как я чувствую, что вы используете скриптлеты как правило, а не как исключение.

person Will Hartung    schedule 03.12.2011

Основываясь на ответе @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 вне обертки. Работает как шарм для меня :)

person Hans Araya    schedule 06.01.2018

Я ищу реальное решение этой проблемы, но обходной путь, который я использую, заключается в создании тега 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>
person Ali Shakiba    schedule 03.12.2011
comment
JSP 2 предпочел бы, чтобы вам не нужно было это делать, но это жизнеспособное решение для тех, у кого устаревший дизайн. Хорошо! - person Thomas W; 24.10.2012

@Пони

Если вы хотите использовать простое условие if, мы можем использовать следующее вместо скриптлета

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

Ниже приведен код, который я использовал для добавления скриптового кода на страницы 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[... ]]> делает свое дело.

Ниже приведены справочные ссылки:

person Charudatta Joshi    schedule 20.08.2018