2013-02-18 6 views
35

devo impostare una variabile nel mio controller il seguente codice:Thymeleaf costruire URL con la variabile

model.set("type", type); 

Nella vista thymeleaf Voglio costruire un modulo con un'azione url:

/mycontroller/{type} 

Tutte le idee come ottenere questo? Ho letto la documentazione di Thymeleaf senza fortuna.

risposta

64

Come user482745 suggests in the comments (ora cancellato), la concatenazione di stringhe ho già suggerito

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

non riuscirà in alcuni contesti web.

Thymeleaf utilizza LinkExpression che risolve l'espressione @{..}. Internamente, questo utilizza HttpServletResponse#encodeURL(String). La sua javadoc afferma

Per robusto monitoraggio della sessione, tutti gli URL emessi da una servlet dovrebbero essere corsa attraverso questo metodo. In caso contrario, la riscrittura dell'URL non può essere utilizzata con i browser che non supportano i cookie.

in applicazioni web in cui il tracciamento sessione viene fatto attraverso l'URL, che parte verrà aggiunto alla stringa emessa per @{..} prima della ${..} viene aggiunto. Tu non vuoi questo.

Invece, le variabili uso di percorso come suggerito nella documentation

È inoltre possibile includere parametri sotto forma di variabili di percorso analogamente ai parametri normali, ma specificando un segnaposto all'interno del percorso tua URL:

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

Quindi il vostro esempio sarà simile

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

Questo non funziona per me. Per l'esempio precedente, otterrei '{user}' reso letteralmente nell'URL. Ad esempio, 'First' mi fornisce un collegamento di 'http: // host/users/{user.first}' con il testo 'Rick'. – Rick

+0

@rick All'interno di '@ {...}' non hai specificato il valore del segnaposto '{user.first}'. Se il mio Thymeleaf è ancora corretto, avrai bisogno di '@ {/ users/{path} (path = $ {user.first})}'. –

+0

Grazie, Sotirios, sembra che sia così. Vorrei davvero poter scrivere '$ {user.first}' (o qualsiasi altra cosa) nel percorso senza tutto il boilerplate. Non capisco davvero perché non supporta un uso così ovvio. – Rick

25

Se non si desidera utilizzare la concatenazione di stringhe (proposed by Sotirios), è possibile utilizzare expression preprocessing in URL link:

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

Penso anche che questa sia una soluzione migliore della soluzione proposta da Sotirios. Ho link come 'th: action =" @ {/ offers/__ $ {offer.id} __/changeStatus} "'. – sebast26

11

È necessario stringa concatenate all'interno @ {}.

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

@ {} viene utilizzato per la riscrittura degli URL. Parte della riscrittura degli URL sta tenendo traccia della sessione. URL di richiesta per la prima volta, il server app aggiunge all'url ;jsessionid=somehexvalue e genera cookie con jsessionid. Quando il client invia un cookie durante la successiva richiesta, il server sa che il client supporta i cookie. Se il server conosce i cookie di supporto del client, il server non manterrà addind jsessionid nell'URL.

Il mio modo preferito è la sostituzione letterale con la sintassi della pipeline (|).

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

percorso Thymeleaf sintassi variabile è

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

Riferimento: Thymeleaf Standard URL Syntax

+1

Preferisco anche la sostituzione letterale, in quanto è più chiara e facile da mantenere. La sintassi del timeleaf è troppo complessa per compiti semplici. –

+0

Fare una concatenazione di stringhe funziona per me, ma è molto brutto. Perché non funziona semplicemente scrivere 'th: href =" @ {/ foo/bar/{obj.property}} "'? Questo non funziona per me. – Rick

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

Ho lo stesso problema e risolvere tramite concatination stringa come di seguito.

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

Quello che vi serve è:

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

Documentazione:

Grande aiuto è qui: http://www.thymeleaf.org/doc/articles/standardurlsyntax.html. Quello che ho usato da non c'era:

È inoltre possibile includere parametri sotto forma di variabili di percorso simile ai parametri normali, ma che specificano un segnaposto all'interno del percorso tua URL:

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

. .. Cosa c'è di più: l'espressione URL del tipo:

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

+0

Una cosa da ricordare è che i parametri devono essere tutti alla fine dell'espressione di collegamento. Questa è la sintassi corretta: '@ {/ ordine/{id} (id = $ {anIdExpression})/dettaglio/{dettaglio} (particolare = $ {aDetailExpression)}' Ma questo è corretto: '@ {/ order/{id}/detail/{detail} (id = $ {anIdExpression}, detail = $ {aDetailExpression)}' I documenti non sono molto chiari su questo punto, quindi ho pensato di salvare gli altri il tempo speso per tentativi ed errori. – rdguam