2013-02-18 20 views
35

Mam następujący kod ustawienia zmiennej w moim kontrolera:Thymeleaf skonstruować URL ze zmienną

model.set("type", type); 

W widoku thymeleaf Chcę skonstruować formularz z akcji URL:

/mycontroller/{type} 

jakieś pomysły jak to osiągnąć? Czytałem dokumentację bez powodzenia.

Odpowiedz

64

Jak user482745 suggests in the comments (skasowany) konkatenacją ciąg ja wcześniej zasugerował

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

zawiedzie w niektórych kontekstach internetowych.

Thymeleaf używa LinkExpression, który rozwiązuje wyrażenie @{..}. Wewnętrznie używa to HttpServletResponse#encodeURL(String). Jego javadoc stwierdza

Dla solidnej śledzenia sesji, wszystkie adresy URL emitowane przez serwlet powinien być prowadzony przez tej metody. W przeciwnym razie, przepisywanie adresów URL nie może być używane z przeglądarkami , które nie obsługują plików cookie.

W aplikacjach internetowych, gdzie śledzenie sesji odbywa się za pomocą adresu URL, że część zostanie dołączona do łańcucha emitowanego przez @{..} przed ${..} jest załączony. Nie chcesz tego.

Zamiast zmienne użycie ścieżki jak zasugerowano w documentation

Można także parametry w postaci zmiennych ścieżek podobnie jak normalne parametry ale określenie zastępczy wewnątrz ścieżki adresu URL za:

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

Twój przykład będzie wyglądał następująco:

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

To nie działa dla mnie. W powyższym przykładzie otrzymam słowo "{user}" dosłownie w adresie URL. Na przykład 'First' daje mi łącze do http: // host/users/{user.first} 'z tekstem' Rick'. – Rick

+0

@rick Wewnątrz '@ {...}' nie określiłeś wartości symbolu zastępczego '{user.first}'. Jeśli mój Thymeleaf nadal jest poprawny, potrzebujesz '@ {/ users/{path} (path = $ {user.first})}'. –

+0

Dzięki, Sotirios, to wydaje się być. Na pewno chciałbym napisać '$ {user.first}' (lub cokolwiek innego) na ścieżce bez całej tablicy. Naprawdę nie rozumiem, dlaczego nie obsługuje tak oczywistego użycia. – Rick

25

Jeżeli nie chcesz używać konkatenacji ciągów (proposed by Sotirios), można użyć expression preprocessing w URL link:

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

Uważam również, że jest to lepsze rozwiązanie niż rozwiązanie proponowane przez Sotirios. Mam linki takie jak 'th: action =" @ {/ offers/__ $ {offer.id} __/changeStatus} "'. – sebast26

11

Trzeba złączyć ciąg wewnątrz @ {}.

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

@ {} służy do przepisywania adresów URL. Częścią przepisywania adresów URL jest śledzenie sesji. Po raz pierwszy URL żądania użytkownika, serwer aplikacji dodaje do adresu url ;jsessionid=somehexvalue i generuje plik cookie z jsessionid. Gdy klient wysyła cookie podczas następnego żądania, serwer wie, że klient obsługuje pliki cookie. Jeśli serwer wie, że pliki cookie obsługujące klienta, serwer nie zachowa addsess jsessionid w adresie URL.

Moim preferowanym sposobem jest dosłowne podstawianie za pomocą składni potoku (|).

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

Thymeleaf ścieżka jest

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

referencyjny: Thymeleaf Standard URL Syntax

+1

Ja również wolę dosłowne zastąpienie, ponieważ jest jaśniejsze i łatwiejsze w utrzymaniu. Składnia thymeleaf jest zbyt skomplikowana do prostych zadań. –

+0

Robienie połączeń ciągowych działa dla mnie, ale jest to bardzo brzydkie. Dlaczego nie wystarczy napisać 'th: href =" @ {/ foo/bar/{obj.property}} "'? To nie działa dla mnie. – Rick

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

Mam ten sam problem i rozwiązać poprzez ciąg concatination jak poniżej.

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

Co trzeba to:

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

Dokumentacja:

Wielką pomoc jest tutaj: http://www.thymeleaf.org/doc/articles/standardurlsyntax.html. Co użyłem stamtąd było:

Można także parametry w postaci zmiennych ścieżek podobnie do normalnych parametrów ale określających zastępczy wewnątrz ścieżki adresu URL za:

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

. .. Co więcej: wyrażenie adresu URL, takie jak:

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

+0

Należy wspomnieć, że wszystkie parametry muszą znajdować się na końcu wyrażenia linku. Jest to błędna składnia: '@ {/ zlecenia/{id} (id = $ {anIdExpression})/detal/{detal} (detail = $ {aDetailExpression)}' Ale to jest poprawne: '@ {/ order/{id}/detail/{szczegół} (id = $ {anIdExpression}, detail = $ {aDetailExpression)}' Dokumenty nie są bardzo jasne w tym punkcie, więc pomyślałem, że będę ocal innych, czas, który spędziłem na próbach i błędach. – rdguam

Powiązane problemy