Spring: Idiomati c способ добавления параметров запроса - PullRequest
0 голосов
/ 29 января 2020

Какой идиоматический c способ в Spring добавить дополнительные параметры запроса к заданному URL? URL-адрес может уже содержать параметры запроса или фрагмент. Конечно, значения параметров должны быть правильно закодированы.

Idiomati c означает, что я ищу краткий код без импорта каких-либо дополнительных библиотек, кроме обычной установки 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 заключается в том, что он не может отменить кодирование процента параметров запроса. Затем я получил смесь закодированных и некодированных параметров с двумя выходами: существующие параметры были неправильно кодированы дважды или дополнительные параметры не были закодированы вообще.

1 Ответ

2 голосов
/ 30 января 2020

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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...