Even though it's an older question, I hope this could still help:
<a th:href="@{${urlBuilder.replaceQueryParam('id', 3).build().toUriString()}}" th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder).fromCurrentRequest()}">
This builds a complete URI string, including the HTTP(S) part. So if you use (for example) a load balancer for your web applications and it doesn't forward https requests directly, you will get a wrong URI string. In this case, you have to do it like Zico wrote: Set the baseUrl in the controller and bind it to the template.
You could also get the query string from the current request: request.getQueryString()
or use the ServletUriComponentsBuilder
class in your controller.
Edit
You can apply .scheme('https')
to urlBuilder
(@{${urlBuilder.replaceQueryParam('id', 3).scheme('https').build().toUriString()}}
). E.g. you can create a method in your controller which gets the X-Forwarded-Proto
from your load balancer.
Check example #27 from here: https://www.programcreek.com/java-api-examples/?api=org.springframework.web.servlet.support.ServletUriComponentsBuilder