JSP теги + скриптлет.Как включить скриптлет? - PullRequest
13 голосов
/ 23 августа 2011

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

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

Ответы [ 7 ]

21 голосов
/ 23 августа 2011

В этом случае контейнер не заботится о значении 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>
6 голосов
/ 16 декабря 2013

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

<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>
4 голосов
/ 03 декабря 2011

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

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

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

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

2 голосов
/ 07 января 2018

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

1 голос
/ 03 декабря 2011

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

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

@ Poni

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

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