[ http://issues.apache.org/struts/browse/WW-1273?page=all ] tm_jee resolved WW-1273: ------------------------
Resolution: Fixed > freemarker 'parameters' model attribute - incorrect TemplateModel > ----------------------------------------------------------------- > > Key: WW-1273 > URL: http://issues.apache.org/struts/browse/WW-1273 > Project: Struts Action 2 > Type: Bug > Components: Views > Versions: WW 2.2.1, WW 2.2.2 > Environment: FreeMarker 2.3.4, 2.3.6; using recommended FreeMarker 'result > type' > Reporter: Vladimir Olenin > Assignee: tm_jee > Priority: Critical > Fix For: 2.0 > > There seems to be a very nasty bug with FreeMarker, which still hasn't been > fixed. To access url parameter values one should use 'parameters' variable > (btw, this is not documented anywhere, eg, it's not on the 'FreeMarker' > integration page in the list of other variable accessible from FreeMarker > view). > The problem with 'parameters' variable is that it seems like incorrect > TemplateModel is currently used, specifically 'ArrayModel', while it should > be 'HashModel' or smth similar. I'm a novice with FreeMarker, so it might > also be something else, but one thing I confirmed is that FreeMarker supplied > freemarker.ext.servlet.FreemarkerServlet exposes url parameters through > RequestParameters attribute correctly and it is using > HttpRequestParametersHashModel). > This bug makes it currently impossible to access parameter values by name, > eg, by using ${parameters.param1} to access 'param1' value in the url > http://smth.com/test.action?param1=xxx. The above attempt will result in the > following exception: > ====================================== > Expecting a string, date or number here, Expression parameters.message is > instead a freemarker.ext.beans.ArrayModel > The problematic instruction: > ---------- > ==> ${parameters.param1} [on line 8, column 13 in test.ftl] > ---------- > Java backtrace for programmers: > ---------- > freemarker.core.NonStringException: Error on line 8, column 15 in test.ftl > Expecting a string, date or number here, Expression parameters.message is > instead a freemarker.ext.beans.ArrayModel > at freemarker.core.Expression.getStringValue(Expression.java:126) > at freemarker.core.Expression.getStringValue(Expression.java:93) > at freemarker.core.DollarVariable.accept(DollarVariable.java:76) > at freemarker.core.Environment.visit(Environment.java:196) > at freemarker.core.MixedContent.accept(MixedContent.java:92) > at freemarker.core.Environment.visit(Environment.java:196) > at freemarker.core.Environment.process(Environment.java:176) > at freemarker.template.Template.process(Template.java:232) > at > com.opensymphony.webwork.views.freemarker.FreemarkerResult.doExecute(FreemarkerResult.java:130) > at > com.opensymphony.webwork.dispatcher.WebWorkResultSupport.execute(WebWorkResultSupport.java:101) > at > com.opensymphony.xwork.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:312) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:207) > at > com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:137) > at > com.opensymphony.xwork.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:81) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:115) > at > com.opensymphony.xwork.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:81) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.webwork.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:171) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:151) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:31) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:100) > at > com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:189) > at > com.opensymphony.xwork.DefaultActionProxy.execute(DefaultActionProxy.java:113) > at > com.opensymphony.webwork.dispatcher.DispatcherUtils.serviceAction(DispatcherUtils.java:233) > at > com.opensymphony.webwork.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:198) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) > at > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) > at > org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) > at > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) > at > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) > at > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) > at > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) > at > org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) > at > org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744) > at > org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) > at > org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80) > at > org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684) > at java.lang.Thread.run(Thread.java:595) > ============================ > while following call: ${parameters}, will printout what seems to be > 'toString' call of List: > {param1=[Ljava.lang.String;@6210fb, param2=[Ljava.lang.String;@48edb5} > As I mentioned, if _original Freemarker's_ FreemarkerServlet is used to > render the view, variable access like ${RequestParameters.param1} work just > fine. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/struts/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]