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.
Now, it is indeed possible that ${parameters.param1} works fine with the Freemarker servlet. In this case, it works as well, but with a twist. After all, all request parameters have String arrays as a value (be it 'hidden'), so the error message (wrong model, array), is because you're trying to print an array rather than a String.
The solution is to use ${parameters.param1[0]}.
Why I mark this as not a problem ? Because you shouldn't directly expose parameters from the request in your view. You should let XWork set the on your Action, and use Freemarker to query your action. So, if you have a String getParam1() in your action, you could do ${param1} in your result. If you have a String[] getParam1(), you would have to do ${param1[0]}. The parameters variable is there to be used when using components or tags (to pass parameters).