2013-02-18 4 views
35

У меня есть настройки переменной в моем контроллере следующий код:Thymeleaf построить URL с переменной

model.set("type", type); 

По мнению thymeleaf Я хочу построить форму с действием URL:

/mycontroller/{type} 

Любые идеи как добиться этого? Я прочитал документацию тимелеафа без везения.

ответ

64

Как user482745 suggests in the comments (теперь удалены), то конкатенация я ранее предложил

<form th:action="@{/mycontroller/} + ${type}"> 

потерпит неудачу в некоторых веб-контекстах.

Thymeleaf использует LinkExpression, который разрешает выражение @{..}. Внутри это используется HttpServletResponse#encodeURL(String). Его Javadoc утверждает

Для надежного отслеживания сеанса, все URL-адрес, испускаемый сервлет должны быть запустить с помощью этого метода. В противном случае переписывание URL-адресов не может использоваться с браузерами, которые не поддерживают файлы cookie.

В веб-приложениях, где отслеживающей осуществляется через URL, то эта часть будет добавлена ​​к строке, излучаемого для @{..} перед ${..} прилагается. Вы не хотите этого.

Вместо переменных использовать путь, как предложено в documentation

Вы можете также включить параметры в виде переменных пути так же, как нормальные параметры, но указав заполнитель внутри вашего URL в пути:

<a th:href="@{/order/{id}/details(id=3,action='show_all')}"> 

Так что ваш пример будет выглядеть

<form th:action="@{/mycontroller/{path}(path=${type})}"> //adding ending curly brace 
+1

Это не работает для меня. В приведенном выше примере я бы получил '{user}' визуализированный буквально в URL. Например, 'First' дает мне ссылку 'http: // host/users/{user.first}' с текстом 'Rick'. – Rick

+0

@rick Внутри '@ {...}' вы не указали значение заполнителя '{user.first}'. Если мой Тимелеаф по-прежнему прав, вам понадобится '@ {/ users/{path} (путь = $ {user.first})}'. –

+0

Спасибо, Сотириос, это похоже. Я уверен, что я мог бы просто написать '$ {user.first}' (или что-то еще) на пути без всего шаблона. Я действительно не понимаю, почему он не поддерживает такое очевидное использование. – Rick

25

Если Вы не хотите использовать конкатенацию (proposed by Sotirios), Вы можете использовать expression preprocessing в URL link:

<form th:action="@{/mycontroller/__${type}__}"> 
+1

Я также считаю, что это лучшее решение, чем решение, предложенное Sotirios. У меня есть ссылки, такие как 'th: action =" @ {/ offers/__ $ {offer.id} __/changeStatus} "'. – sebast26

11

Вам нужно сцепить строки внутри @ {}.

<form th:action="@{'/mycontroller/' + ${type}}"> 

@ {} используется для перезаписи URL-адресов. Часть перезаписи URL-адресов отслеживает сеанс. Первый URL-адрес пользовательского запроса, сервер приложений добавляет URL-адрес ;jsessionid=somehexvalue и создает cookie с jsessionid. Когда клиент отправляет cookie во время следующего сервера запросов, клиент поддерживает файлы cookie. Если сервер знает, что куки-файлы поддержки клиентов, сервер не будет содержать addind jsessionid в URL-адресе.

Мой предпочтительный способ - это буквальная подстановка синтаксисом конвейера (|).

<form th:action="@{|/mycontroller/${type}|}"> 

Thymeleaf путь переменной Синтаксис

<form th:action="@{/mycontroller/{pathParam}(pathParam=${type}}"> 

Ссылка: Thymeleaf Standard URL Syntax

+1

Я также предпочитаю буквальную замену, поскольку она более понятная и простая в обслуживании. Синтаксис тимелеафа слишком сложный для простых задач. –

+0

Выполнение конкатенирования строк работает для меня, но это очень уродливо. Почему он просто не работает, чтобы написать 'th: href =" @ {/ foo/bar/{obj.property}} "'? Это не работает для меня. – Rick

0
Exception evaluating SpringEL expression: "businessId" (login:50) 

У меня та же проблема, и решить с помощью строки concatination, как показано ниже.

LoginController.java

@RequestMapping(value = "/login/{businessId}", method = RequestMethod.GET) 
    public ModelAndView get(HttpServletRequest request, @PathVariable String businessId) { 
     ModelAndView modelAndView = new ModelAndView("login"); 
     modelAndView.addObject("businessId", businessId); 
     return modelAndView; 
    } 

login.html

  <form role="form" th:action="@{/login} + '/'+ ${businessId}" th:method="post"> 
          <fieldset> 
           <div class="form-group"> 
            <input class="form-control" placeholder="E-mail" name="userName" 
             type="email"></input> 
           </div> 
           <div class="form-group"> 
            <input class="form-control" placeholder="Password" 
             name="password" type="password" value=""></input> 
           </div> 
           <div class="checkbox"> 
            <label> <input name="remember" type="checkbox" 
             value="Remember Me"></input>Remember Me 
            </label> 
           </div> 
           <!-- Change this to a button or input when using this as a form --> 
           <button id="login" class="btn btn-lg btn-success btn-block" type="submit">Login</button> 
          </fieldset> 
      </form> 
0

Что вам нужно это:

<a th:href="@{/mycontroller/{type}(type=${type})}"> 

Документация:

Большую помощь здесь: http://www.thymeleaf.org/doc/articles/standardurlsyntax.html. Что я оттуда было:

Вы можете также включить параметры в виде пути переменных аналогичны к нормальным параметрам, но задающему заполнитель внутри пути вашего URL в:

<a th:href="@{/order/{id}/details(id=3,action='show_all')}">

. .. К тому же: выражение в формате URL:

<a th:href="@{/order/details(id=${order.id})}">

+0

Следует упомянуть, что все параметры должны быть в конце выражения ссылки. Это неверно синтаксис: '@ {/ заказ/{ID} (идентификатор = $ {anIdExpression})/подробно/{подробно} (подробно = $ {aDetailExpression)}' Но это правильно: '@ {/ order/{id}/detail/{detail} (id = $ {anIdExpression}, detail = $ {aDetailExpression)}' Документы не очень понятны в этом вопросе, поэтому я думал, что буду за исключением других людей время, которое я провел на проб и ошибок. – rdguam