Чтение RequestParameters в шаблоне Freemarker с помощью Spring MVC

Я искал весь Интернет в поисках ответа, но не мог его найти. Я надеюсь, что кто-то имел дело с такой же проблемой.

Я разрабатываю приложение на основе Spring MVC (3.1) и Freemarker (2.3.16). Моя конфигурация Freemarker выглядит так:

 <!--  FreeMarker parsing -->
 <bean id="freemarkerConfig"  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath"  value="/WEB-INF" />

     <property name="freemarkerSettings"> 
        <props>
             <prop key="default_encoding">UTF-8</prop>
             <prop key="output_encoding">UTF-8</prop>
        </props>
     </property>

 </bean>


 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
      <property name="cache" value="true" />
      <property name="prefix" value="/views/" />
      <property name="suffix" value=".ftl" />

      <property name="requestContextAttribute" value="rc"></property>

      <!-- if you want to use the Spring FreeMarker macros, set this property to true -->
      <property name="exposeSpringMacroHelpers" value="true" />

      <property name="contentType" value="text/html;charset=UTF-8"></property>

      <property name="exposeRequestAttributes" value="true" />
          <property name="exposeSessionAttributes" value="true" />

 </bean>

Это довольно просто. У меня нет проблем с рендерингом layout/views. Проблема связана с контроллером Spring и записью параметров запроса. Мое простейшее возможное действие контроллера выглядит так:

@RequestMapping(value={"/simplest/action","/simplest"}, method=RequestMethod.GET)
 @Transactional
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

     ModelAndView mv = new ModelAndView("/simplest/action");        
     mv.addObject("myCustomIdFromView",  "66666" );
     return mv;
  }

Представление отрисовано успешно. В этом представлении я использую такую ​​конструкцию:

<input type="hidden" name="myCustomIdFromView" id="myCustomIdFromView" value="${myCustomIdFromView}" />

Но с такой конструкцией Freemarker не представляет никакой ценности. Если я изменю свой ввод на:

<input type="hidden" name="myCustomIdFromView" id="myCustomIdFromView" value="${myCustomIdFromView!'default'}" />

Тогда «по умолчанию» отображается правильно. Поэтому я переключился на RequestParameters. И еще одна странность. С конструкциями:

{$RequestParameters.myCustomIdFromView}
{$RequestParameters['myCustomIdFromView']}

Я получаю пустые значения Freemarker 'undefined'.

Я наконец пришел к такому решению.

<#assign myCustomIdFromView = '' />
<#list RequestParameters?keys as key>
 <#if key == 'myCustomIdFromView'>
    <#assign myCustomIdFromView = RequestParameters[key] />
    ${myCustomIdFromView}
 </#if>
</#list>

И ЭТО РАБОТАЕТ! Может ли кто-нибудь сказать мне, почему у меня проблемы с такой простой вещью, как передача аргумента в ModelAndView и его рендеринг в шаблоне? Значения (как вы можете видеть) находятся в параметрах модели/запроса, но именно Freemarker вызывает проблему? Любая помощь приветствуется.

С уважением, Хлебик


person Chlebik    schedule 02.07.2012    source источник
comment
${myCustomIdFromView!'default'} печатает default, а ${myCustomIdFromView} не генерирует исключение? Это так неправильно... Я надеюсь, что Spring MVC не настраивает FreeMarker таким образом. Кроме того, я полагаю, что RequestParameters относится к строке запроса HTTP и параметрам формы, а не к атрибутам объекта запроса (я полагаю, что это Request.theAttributeName). Что я получаю пустые значения Freemarker 'undefined'. в смысле все-таки?   -  person ddekany    schedule 02.07.2012
comment
Написал не очень понятно - получаю стандартное сообщение: 'freemarker.core.InvalidReferenceException: Expression myCustomIdFromView is undefined'   -  person Chlebik    schedule 02.07.2012
comment
Последний пример по-прежнему не имеет смысла. Он печатает 6666? Это было бы странно (если только у вас нет параметра запроса или поля формы с именем myCustomIdFromView). Даже в этом случае пример можно было бы упростить до ${RequestParameters.myCustomIdFromView!''}.   -  person ddekany    schedule 02.07.2012
comment
Кстати, что печатает <#list .data_model?keys as k>${k},</#list>?   -  person ddekany    schedule 02.07.2012
comment
@ddekany - печатает 6666. Я знаю, что это странно - поэтому я ищу помощи. Данное выражение выводит: flash,org.springframework.validation.BindingResult.cont,org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER,org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE,org.springframework.web.servlet.DispatcherServlet. THEME_RESOLVER, org.springframework.web.servlet.DispatcherServlet.CONTEXT,   -  person Chlebik    schedule 02.07.2012
comment
RequestParameters, org.springframework.core.convert.ConversionService, springMacroRequestContext, actionName, org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping, Request, JspTaglibs, myCustomIdFromView, rc, org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP, controllerName, Сессия, Приложение, org.springframework.web.servlet.HandlerMapping.uriTemplateVariables, org.springframework.web.servlet.HandlerMapping.bestMatchingPattern, cont, org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER   -  person Chlebik    schedule 02.07.2012
comment
Как видите, в списке есть моя переменная.   -  person Chlebik    schedule 02.07.2012
comment
Ну я со Spring не дружу, так почему ${RequestParameters.myCustomIdFromView} вообще работает (так ли это?), не знаю, может у него есть откат к модели. Что бы ни. Что я знаю, так это то, что если .data_model действительно содержит myCustomIdFromView, то единственный способ, которым ${myCustomIdFromView} потерпит неудачу, - это если его значение равно null (проверьте с ${.data_model.myCustomIdFromView!'null'}), или если где-то что-то присвоит null другой переменной myCustomIdFromView, которая находится в текущее пространство имен FreeMarker или является локальной переменной FreeMarker.   -  person ddekany    schedule 02.07.2012


Ответы (1)


Я узнал, что было не так. Я использую Spring MVC. Поэтому существует правило по умолчанию, которое гласит, что все -servlet.xml файлы конфигурации будут загружены по умолчанию.

В моем frontcontroller-servlet.xml у меня был оператор import, который включал базу applicationContext.xml. В этом файле у меня есть еще 3 импорта (для поддержки дефрагментации файлов конфигурации - с конфигом для БД, контроллеров и т.д.).

Но в web.xml также было указано:

 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext*</param-value>
</context-param>

И результатом объединения этих двух вещей стало двойное создание стандартных bean-компонентов Spring. Это выяснилось, когда я начал интегрироваться с Spring Security - внезапно мое приложение не удалось развернуть - и исключения указывали на существующие двойные bean-компоненты (аннотация @Autowire сошла с ума).

Поэтому я предполагаю, что глубоко внутри Freemarker классов для Spring (или в самом Spring) что-то произошло и существовали две модели (с параметрами запроса). Прямо сейчас - когда я использую код из моего вопроса, все отображается правильно.

person Chlebik    schedule 03.07.2012