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


这些网址:

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/

相关文章:

apache - mod_rewrite 在 url 中有空格

url - "/../"的含义是 URL 中的父目录标准吗?

java - 如何按Java中的元素数对2D字符串数组进行排序

java - 用Java调试面向对象的编程代码输出

java - 如何根据DataProvider提供的测试参数修改TestNG/Allure(@Test(description),@ Description,@ TmsLink)值

java - 将元数据添加到 java throwable 对象

php - 检查 URL 是否包含特定路径的语句?

java - RSA_verify中预期的数据类型是什么,无法验证从Java生成的签名

java - 在重新生成jHipster实体时如何防止自定义存储库方法被删除

java - 如何在创建时将值赋给对象,该对象将String和ArrayList值作为参数?