Spring:添加查询参数的惯用方法



Spring 中向给定 URL 添加其他查询参数的惯用方法是什么?URL 可能已包含查询参数或片段。当然,参数值必须正确编码。

习惯性意味着我正在寻找简洁的代码,而无需导入除典型 Spring 引导安装之外的任何其他库。

该方法应具有以下签名:

/**
Add additional query parameters to the specified URL.
@param url the URL
@param params map with additional query parameters (parameter name/value pairs)
@return the new URL
*/
String addQueryParameters(String url, Map<String, String> params);

给定这些附加参数:

price: €25
name: Réne e Suzanne
config: {"f1":34,"f2":"&?"}

以及这些网址:

http://www.app.com/one%20two/
http://www.berry.nz/one/two?return=%7B%22abc%22%3A%22%25%5E%3F%22%7D
http://www.soil.au:8080/one/two#section-2

预期成果应为:

http://www.app.com/one%20two/?price=%E2%82%AC25&name=R%C3%A9ne+e+Suzanne&config=%7B%22f1%22%3A34%2C%22f2%22%3A%22%26%3F%22%7D
http://www.berry.nz/one/two?return=%7B%22abc%22%3A%22%25%5E%3F%22%7D&price=%E2%82%AC25&name=R%C3%A9ne+e+Suzanne&config=%7B%22f1%22%3A34%2C%22f2%22%3A%22%26%3F%22%7D
http://www.soil.au:8080/one/two?price=%E2%82%AC25&name=R%C3%A9ne+e+Suzanne&config=%7B%22f1%22%3A34%2C%22f2%22%3A%22%26%3F%22%7D#section-2

顺便说一句:这是针对严肃软件的(没有家庭作业(。我试图用UriComponentsBuilder解决它并失败了... :-(

更新

UriComponentsBuilder的问题在于它无法撤消查询参数的百分比编码。然后,我最终混合了编码和未编码的参数,并有两个输出:现有参数被错误地双重编码或附加参数根本没有编码。

URL 有点难以编码,因为不同的编码类型是混合的。例如,URL 中的空格编码为%20,而查询参数中的空格编码为+。因此,我创建了一个encodeUtf8方法来单独编码查询参数:

import org.junit.Test;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import static org.assertj.core.api.Assertions.assertThat;
public class SomeTest {
@Test
public void test1() throws Exception {
String url = UriComponentsBuilder.fromUriString("http://www.app.com/one%20two/")
.queryParam("price", encodeUtf8("€25"))
.queryParam("name", encodeUtf8("Réne e Suzanne"))
.queryParam("config", encodeUtf8("{"f1":34,"f2":"&?"}"))
.build()
.toUriString();
assertThat(url).isEqualTo("http://www.app.com/one%20two/?price=%E2%82%AC25&name=R%C3%A9ne+e+Suzanne&config=%7B%22f1%22%3A34%2C%22f2%22%3A%22%26%3F%22%7D");
}
@Test
public void test2() throws Exception {
String url = UriComponentsBuilder.fromUriString("http://www.berry.nz/one/two?return=%7B%22abc%22%3A%22%25%5E%3F%22%7D")
.queryParam("price", encodeUtf8("€25"))
.queryParam("name", encodeUtf8("Réne e Suzanne"))
.queryParam("config", encodeUtf8("{"f1":34,"f2":"&?"}"))
.build()
.toUriString();
assertThat(url).isEqualTo("http://www.berry.nz/one/two?return=%7B%22abc%22%3A%22%25%5E%3F%22%7D&price=%E2%82%AC25&name=R%C3%A9ne+e+Suzanne&config=%7B%22f1%22%3A34%2C%22f2%22%3A%22%26%3F%22%7D");
}
@Test
public void test3() throws Exception {
String url = UriComponentsBuilder.fromUriString("http://www.soil.au:8080/one/two#section-2")
.queryParam("price", encodeUtf8("€25"))
.queryParam("name", encodeUtf8("Réne e Suzanne"))
.queryParam("config", encodeUtf8("{"f1":34,"f2":"&?"}"))
.build()
.toUriString();
assertThat(url).isEqualTo("http://www.soil.au:8080/one/two?price=%E2%82%AC25&name=R%C3%A9ne+e+Suzanne&config=%7B%22f1%22%3A34%2C%22f2%22%3A%22%26%3F%22%7D#section-2");
}
private static String encodeUtf8(String val) throws UnsupportedEncodingException {
return URLEncoder.encode(val, "UTF-8");
}
}

最新更新