Подтвердить что ты не робот

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

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

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

До сих пор я получаю эту ошибку "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:

Идеальный код будет выглядеть как, внутри страницы, использующей мой шаблон ('wrapper', как указано выше):

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

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

4b9b3361

Ответ 1

В этом случае контейнер не заботится о значении scripting-invalid в web.xml, потому что он просматривает метаданные тега для jsp:body, у которого значение body-content 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>

Ответ 2

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

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

Ответ 3

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

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

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

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

Ответ 4

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

Ответ 5

@Poni

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

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

Ответ 6

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