Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thymeleaf: add parameter to current url

Tags:

I'm at

http://example.com/some/page?p1=11 

and I want to add a parameter to current url without having to redefine it:

http://example.com/some/page?p1=11&p2=32 

with something like:

<a th:href="@{?(p2=32)}">Click here</a> 

but the above code return http://example.com/some/page?&p2=32 (removes the p1 parameter).

How can I do it using Thymeleaf?

like image 879
Andrea Avatar asked Dec 23 '14 15:12

Andrea


2 Answers

You can use URI builder, directly from Thymeleaf.

<span th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder).fromCurrentRequest()}"       th:text="${urlBuilder.replaceQueryParam('p2', '32').toUriString()}"> </span> 

For URL http://example.com/some/page?p1=11 prints out:

http://example.com/some/page?p1=11&p2=32 

Explained:

  • SpEL T operator is used for accessing ServletUriComponentsBuilder type.
  • An instance created by factory method fromCurrentRequest is saved to urlBuilder variable.
  • A param is added or replaced in the query string by replaceQueryParam method, and then the URL is built.

Pros:

  • Safe solution.
  • No trailing ? in case of empty query string.
  • No extra bean in Spring context.

Cons:

  • It is quite verbose.

! Be aware that solution above creates one instance of the builder. This means that the builder cannot be reused because it still modifies an original URL. For multiple URLs on a page you have to create multiple builders, like this:

<span th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder)}">     <span th:text="${urlBuilder.fromCurrentRequest().replaceQueryParam('p2', 'whatever').toUriString()}"></span>     <span th:text="${urlBuilder.fromCurrentRequest().replaceQueryParam('p3', 'whatever').toUriString()}"></span>     <span th:text="${urlBuilder.fromCurrentRequest().replaceQueryParam('p4', 'whatever').toUriString()}"></span> </span> 

For http://example.com/some/page prints:

http://example.com/some/page?p2=whatever  http://example.com/some/page?p3=whatever      http://example.com/some/page?p4=whatever 
like image 144
Václav Kužel Avatar answered Oct 12 '22 11:10

Václav Kužel


The easiest solution is concatenating "requestURI" and "queryString". Here is example:

<div th:with="currentUrl=(${#httpServletRequest.requestURI + '?' + #strings.defaultString(#httpServletRequest.queryString, '')})">    <a th:href="@{${currentUrl}(myparam=test)}">click here</a> </div> 

Result for "http://localhost:8080/some-page?param1=1":

 http://localhost:8080/some-page?param1=1&myparam=test 

Result for "http://localhost:8080/some-page":

 http://localhost:8080/some-page?&myparam=test 

Drawback:
Thymeleaf doesn't overwrite parameters - only adds parameters to URL. So if you user click once again to that URL, the result will be:

http://localhost:8080/some-page?param1=1&myparam=test&myparam=test 

References:
http://forum.thymeleaf.org/How-to-link-to-current-page-and-exchange-parameter-td4024870.html

EDIT:

Here is some workaround, which removes parameter "myparam" from the URL:

<div th:with="currentUrl=(${@currentUrlWithoutParam.apply('myparam')})">     <a th:href="@{${currentUrl}(myparam=test)}">click here</a> </div> 

Next in Spring configuration:

@Bean public Function<String, String> currentUrlWithoutParam() {     return param ->   ServletUriComponentsBuilder.fromCurrentRequest().replaceQueryParam(param).toUriString(); } 

For more "global" solution, I would try extending processor for attribute "th:href" or creating my own attribute. I'm not a thymeleaf expert, just facing similar problem.

like image 45
Raf Avatar answered Oct 12 '22 10:10

Raf