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

у меня есть страница, которая использует шаблон тег. Моя паутина.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 / теги / обертка.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>
.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>

Итак, как мне использовать чистые скрипты в моем tag'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>

посмотреть? Скрипты между & внутри " тегов. Именно этого я и пытаюсь достичь.

7 ответов


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

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

контейнер жалуется на содержимое jsp: тело, которое должно быть без скрипта. Если вы хотите отобразить содержимое скриптлета в теле, вы можете установить его как атрибут страницы вне тега jsp: body с помощью скриптлета, а затем отобразить его с помощью EL внутри тела вот так:

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

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

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

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

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

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

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

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


основываясь на ответе @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>

почти так же, как у бьярниджа, но мне пришлось поставить c:set за пределами оболочки. Работает как шарм для меня :)


Я ищу реальное решение этой проблемы, но обходной путь, который я использую, - создать тег 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>

@Poni

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

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

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

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