java - Spring:添加查询参数的惯用方式

标签 java spring url

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

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

该方法应具有以下签名:

/**
 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":"&?"}

以及这些 URL:

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");
    }
}

关于java - Spring:添加查询参数的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59974915/

相关文章:

java - 如何在嵌套 switch 语句中显示图像?

java - Spring 管理属性的最佳方式

java - Spring 休息模板

javascript - 将内容加载到覆盖层并使用其 URL

python - Django:如何获取 url 路径?

java - Spring Framework 3.0中如何在所有页面显示相同的数据?

Java如何使JFrames最大化但不可调整大小

java - 无法打开sqlite数据库,指定的目录或数据库文件不存在

java - 如何使用 @Transactional 注释测试方法

django - 检查重定向网址是否存在