一尘不染

JSTL fmt库抛出500错误,需要启用会话吗?

jsp

我正在Google App Engine上开发一个简单的servlet / JSP,数据驱动的网站。我已经开始在某些数据输入表单上使用JSTL
fmt库,并在使用标签时收到以下与会话相关的错误<fmt:dateFormat> and <fmt:numberFormat>:

[java] java.lang.RuntimeException:在appengine-
web.xml中未启用会话支持。要启用会话,请在该文件中放入true。没有它,则允许getSession(),但不能操纵sessionattributes。

我的JSP中的代码例如是:

<c:forEach var="item" items="${dayList}" >
 <option><fmt:formatNumber value="${item}" pattern="00"/></option>
</c:forEach>

要么

<jsp:useBean id="now" scope="page" class="java.util.Date" />
Now: ${now}<br/>
Year: <fmt:formatDate value="${now}" pattern="yyyy" />

当我注释掉这些行时,重新打开页面后将呈现错误。

我没有启用会话,因为在此Web应用程序中不需要会话,请阅读最好不要这样做。我已经确认没有属性是基于会话的,在NetBeans项目中唯一出现的“会话”是在web.xml中:

<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>

在appengine-web.xml上启用会话后,一切正常。

我的研究指出了可以在web.xml中设置的一些与语言环境相关的上下文参数,即:

<context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name>
    <param-value>en-US</param-value>
</context-param>
<context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
    <param-value>en-US</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.timeZone</param-name>
    <param-value>EDT</param-value>
</context-param>

我已经重新设置了这些参数(并关闭了会话),并得到了相同的错误。

JSTL fmt库似乎很方便用于日期和数字等Web表单,尽管到最后,我可能只需要启用会话并继续前进-
但是我缺少什么吗?这里是有关导致默认情况下引用会话的语言环境设置的?这可能是App Engine特有的吗?

谢谢

PS这是禁用会话时获得的堆栈跟踪:

 [java] Aug 17, 2010 2:41:26 AM com.google.apphosting.utils.jetty.JettyLogger warn
 [java] WARNING: /manage/events/new
 [java] java.lang.RuntimeException: Session support is not enabled in appengine-web.xml.  To enable sessions, put <sessions-enabled>true</sessions-enabled> in that file.  Without it, getSession() is allowed, but manipulation of sessionattributes is not.
 [java]         at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.throwException(StubSessionManager.java:67)
 [java]         at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.setAttribute(StubSessionManager.java:63)
 [java]         at org.apache.jasper.runtime.PageContextImpl.doSetAttribute(PageContextImpl.java:340)
 [java]         at org.apache.jasper.runtime.PageContextImpl.access$300(PageContextImpl.java:64)
 [java]         at org.apache.jasper.runtime.PageContextImpl$4.run(PageContextImpl.java:314)
 [java]         at java.security.AccessController.doPrivileged(Native Method)
 [java]         at org.apache.jasper.runtime.PageContextImpl.setAttribute(PageContextImpl.java:312)
 [java]         at org.apache.taglibs.standard.tag.common.fmt.SetLocaleSupport.setResponseLocale(SetLocaleSupport.java:209)
 [java]         at org.apache.taglibs.standard.tag.common.fmt.SetLocaleSupport.doEndTag(SetLocaleSupport.java:108)
 [java]         at org.apache.jsp.WEB_002dINF.update_005fevent_jsp._jspx_meth_fmt_setLocale_0(update_005fevent_jsp.java:362)
 [java]         at org.apache.jsp.WEB_002dINF.update_005fevent_jsp._jspService(update_005fevent_jsp.java:117)
 [java]         at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
 [java]         at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
 [java]         at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
 [java]         at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
 [java]         at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
 [java]         at com.google.appengine.tools.development.PrivilegedJspServlet.access$101(PrivilegedJspServlet.java:23)
 [java]         at com.google.appengine.tools.development.PrivilegedJspServlet$2.run(PrivilegedJspServlet.java:59)
 [java]         at java.security.AccessController.doPrivileged(Native Method)
 [java]         at com.google.appengine.tools.development.PrivilegedJspServlet.service(PrivilegedJspServlet.java:57)
 [java]         at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
 [java]         at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
 [java]         at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
 [java]         at com.cj.trim.trimFilter.doFilter(Unknown Source)
 [java]         at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
 [java]         at com.queerartfilm.web.JSTLConfigFilter.doFilter(JSTLConfigFilter.java:114)
 [java]         at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
 [java]         at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:51)
 [java]         at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
 [java]         at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
 [java]         at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
 [java]         at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
 [java]         at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
 [java]         at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
 [java]         at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
 [java]         at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
 [java]         at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
 [java]         at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
 [java]         at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
 [java]         at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
 [java]         at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:349)
 [java]         at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
 [java]         at org.mortbay.jetty.Server.handle(Server.java:326)
 [java]         at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
 [java]         at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
 [java]         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
 [java]         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
 [java]         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
 [java]         at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
 [java]         at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

阅读 293

收藏
2020-06-08

共1个答案

一尘不染

真是不幸 看来您无法解决这个问题。然后最好的选择是创建自定义的EL函数,该函数将执行相同的操作。这是一个如何替换的示例fmt:formatDate

首先创建一个EL函数类(只是一个简单的静态类):

package com.example;

import java.text.SimpleDateFormat;
import java.util.Date;

public final class Functions {

    private Functions() {
        //
    }

    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

}

然后创建一个/WEB-INF/functions.tld(注意:以JSP 2.1为目标,不确定您的GAE支持什么,它可能是Servlet
2.4,如果是,则需要将其重新声明为JSP 2.0 taglib):

<?xml version="1.0" encoding="UTF-8" ?>

<taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

    <display-name>Custom Functions</display-name>    
    <tlib-version>1.0</tlib-version>
    <uri>http://example.com/functions</uri>

    <function>
        <name>formatDate</name>
        <function-class>com.example.Functions</function-class>
        <function-signature>java.lang.String formatDate(java.util.Date, java.lang.String)</function-signature>
    </function>
</taglib>

然后,可以在JSP中如下使用它:

<%@taglib uri="http://example.com/functions" prefix="f" %>
<jsp:useBean id="date" class="java.util.Date" />
...
<p>Current year: ${f:formatDate(date, 'yyyy')}</p>
2020-06-08