У меня странная проблема с urlencoding знаком плюса +
в качестве параметра запроса для запроса к API. В документации к API указано:Проблема с кодировкой странного url
Дата должна быть в формате W3C, например. '2016-10-24T13: 33: 23 + 02: 00'.
До сих пор так хорошо, поэтому я использую этот код (minimalized) для генерации URL, используя UriComponentBuilder весны:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX");
ZonedDateTime dateTime = ZonedDateTime.now().minusDays(1);
String formated = dateTime.format(formatter);
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(baseUrl);
uriComponentsBuilder.queryParam("update", formated);
uriComponentsBuilder.build();
String url = uriComponentsBuilder.toUriString();
неперекодированный запрос будет выглядеть следующим образом:
https://example.com?update=2017-01-05T12:40:44+01
кодированные результаты: строка в
https://example.com?update=2017-01-05T12:40:44%2B01
который (ИМХО) правильно закодированный запрос Строка. См. %2B
, заменяя +
на +01
в конце строки запроса.
Теперь, когда я отправляю запрос против API с использованием кодированного URL-адреса, я получаю сообщение об ошибке, когда запрос не может быть обработан.
Однако, если я заменю %2B
с +
перед отправкой запроса, он работает:
url.replaceAll("%2B", "+");
Из моего понимания, +
знака является заменой для whitespace
. Таким образом, URL, что сервер действительно видит после декодирования должен быть
https://example.com?update=2017-01-05T12:40:44 01
Правильно ли я с этим предположением?
Есть ли что-нибудь, что я могу сделать, кроме как связаться с владельцем API, чтобы заставить его работать с использованием правильно закодированного запроса, кроме странных нестандартных замен строк?
UPDATE:
В соответствии со спецификацией RFC 3986 (раздел 3.4), то +
знака в парах запроса не должен быть закодирован.
3.4. Компонент запроса
Запрос содержит не-иерархические данные, которые, наряду с данных в компоненте пути (раздел 3.3), служит для идентификации
ресурса в рамках схемы URI, и присвоения имени органа
(если таковые имеются). Компонент запроса указывается первым вопросом
символом метки («?») И заканчивается знаком числа («#»)
или к концу URI.Berners-Lee, et al. Стандарты Track [Page 23] RFC 3986 URI Generic Syntax
января 2005query = *(pchar/"/"/"?")
Символы слэш ("/") и знак вопроса ("?") Могут представлять данные внутри компонента запроса. Учтите, что некоторые старые, ошибочные реализации не может обрабатывать такие данные правильно, когда он используется в качестве , основание URI для относительных ссылок (раздел 5.1), по-видимому
, потому что они не могут отличить данные запроса по данным пути, когда
ищет иерархическое сепараторы. Тем не менее, в качестве компонентов запроса
часто используется для передачи идентификационной информации в форме
«ключ = значение» пара и один часто используемого значения является ссылкой на
другого URI, иногда лучше, для удобства использования, чтобы избежать percent-
кодировка этих символов.
Согласно this answer on stackoverflow, пружина UriComponentBuilder использует эту спецификацию, но, похоже, на самом деле это не так. Итак, новый вопрос: как заставить UriComponentBuilder следовать спецификациям?
Обратитесь к таблице, представленной @Simon Tewsi http://stackoverflow.com/questions/575440/url-encoding- используя-c-sharp – Prabu
@Prabu, Ваша ссылка не отвечает на вопрос. OP хочет знать, почему служба принимает только знак некодированного плюса, а не как его кодировать или нет, или какие утилиты C# использовать. Быстрая проверка правил кодирования указывает, что обстоятельства, при которых зарезервированные символы кодируются или должны быть закодированы, слегка изменились, но я не видел ничего, чтобы предположить, что знак плюса, используемый как часть форматированной строки даты, не должен быть закодирован. – arcy
Это то, что я тоже думаю @arcy – Michael