Thymeleaf:向当前URL添加参数

23

我在

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

我想在不重新定义当前网址的情况下添加一个参数:

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

类似这样:

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

但是上面的代码返回 http://example.com/some/page?&p2=32 (移除了p1参数)。

我该如何使用Thymeleaf实现这个功能?


截至2016年春季,真的还没有适当的处理方法吗? - Priidu Neemre
6个回答

28
您可以直接使用Thymeleaf中的URI构建器。
<span th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder).fromCurrentRequest()}"
      th:text="${urlBuilder.replaceQueryParam('p2', '32').toUriString()}">
</span>

对于网址http://example.com/some/page?p1=11,输出如下:
http://example.com/some/page?p1=11&p2=32

解释:

  • 使用SpEL T 操作符 来访问 ServletUriComponentsBuilder 类型。
  • 通过工厂方法 fromCurrentRequest 创建的实例被保存到 urlBuilder 变量中。
  • 通过 replaceQueryParam 方法在查询字符串中添加或替换参数,然后构建URL。

优点:

  • 安全的解决方案。
  • 如果查询字符串为空,则不会有拖尾的 ?
  • Spring上下文中没有额外的bean。

缺点:

  • 相当冗长。

!请注意,上述解决方案创建了一个构建器实例。这意味着该构建器不能被重用,因为它仍然修改原始URL。对于页面上的多个URL,您必须创建多个构建器,如下所示:

<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>

对于http://example.com/some/page,输出如下:

http://example.com/some/page?p2=whatever 
http://example.com/some/page?p3=whatever     
http://example.com/some/page?p4=whatever

将多个参数替换为多个 replaceQueryParam,您可以像这样使用 ${urlBuilder.replaceQueryParam('page', current).replaceQueryParam('size', page.size).toUriString()。对于未来的任何人来说,这都是适用的。 - Rahmat Nazali Salimi
我该如何将'p4'设置为'two,values'?而不是创建两个参数,像&p4=two&p4=values,而应该是&p4=two,values。 - netzding
我已经想通了,我只是将它作为列表的第一个参数传递,就像 {'two,values'}。 - netzding
1
你需要使用.build().toUriString()来避免p=%25再次被编码为p=%2525 - bitdancer
在Thymeleaf 3.1.2版本中不再起作用。 - Eduardo Guimaraes

20
最简单的解决方案是将“requestURI”和“queryString”连接起来。(以下是示例:)
<div th:with="currentUrl=(${#httpServletRequest.requestURI + '?' + #strings.defaultString(#httpServletRequest.queryString, '')})">
   <a th:href="@{${currentUrl}(myparam=test)}">click here</a>
</div>

"http://localhost:8080/some-page?param1=1"的结果为:

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

"http://localhost:8080/some-page"的结果为:

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

缺点:
Thymeleaf不会覆盖参数,只会将参数添加到URL中。所以,如果用户再次点击该URL,结果将是:
http://localhost:8080/some-page?param1=1&myparam=test&myparam=test

参考资料:
http://forum.thymeleaf.org/How-to-link-to-current-page-and-exchange-parameter-td4024870.html

编辑:

这里有一个解决方法,可以从URL中删除参数“myparam”:

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

接下来在Spring配置中:

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

为了实现更 "全局" 的解决方案,我建议尝试扩展属性 "th:href" 的处理器或者创建自己的属性。我不是 thymeleaf 专家,只是面临类似的问题。

解决这个问题的方法是创建一个没有我们想要添加参数的基础URL。 - Raf
在第一种情况下:务必使用${#httpServletRequest.requestURI + '?' + #strings.defaultString(#httpServletRequest.queryString, '')},以避免将null附加到您的URL中。 - Priidu Neemre
1
感谢您注意到“queryString”可能为空。链接至javadoc - Raf

3
th:href="@{/your/link?parameter=__${appendParameter}__}"

2
请注意,这需要使用 __(双下划线)才能运行,这些不会出现在结果中。 - Hans Kesting

2
根据文档,您可以指定所有参数。
th:href="@{http://example.com/some/page(p1=11,p2=32)}"

你可以使用表达式获取值:

th:href="@{http://example.com/some/page(p1=11,p2=${someid})}"

1

基于Raf答案,我最终得出了这个解决方案:

@Bean
public BiFunction<String, String, String> replaceOrAddParam() {
  return (paramName, newValue) -> ServletUriComponentsBuilder.fromCurrentRequest()
        .replaceQueryParam(paramName, newValue)
        .toUriString();
}

<a th:href="${@replaceOrAddParam.apply('myParamName', 'myNewValue')}">Text</a>

0

这将适用于您,即使在Unicode中:

 <ul class="pagination">
                <li th:if="${currentPage > 1}"><a th:href="'/search?key=' + ${param.key[0]} + '&amp;page=' +   ${currentPage-1}">Previous</a></li>

                      <li th:each="i : ${#numbers.sequence( 1, total+1)}" th:class="${i==currentPage}?active:''">
                            <a th:href="'/search?key=' + ${param.key[0]} + '&amp;page=' +   ${i}" th:inline="text">
                            [[${i}]] <span  class="sr-only">(current)</span>
                            </a>
                      </li>
                      <li><a th:if="${total + 1 > currentPage}" th:href="'/search?key=' + ${param.key[0]} + '&amp;page=' +   ${currentPage+1}">Next</a></li>
            </ul>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接