Я столкнулся с интересной проблемой при работе над некоторыми интеграционными тестами.
У меня есть конечная точка отдыха, у которой есть некоторые параметры запроса, которые являются отметками времени, указанными в ISO-8601 (например: 2020-07-08T23: 54 : 36.931159 + 03: 00). Даты форматируются с использованием java .time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME
Я создаю адрес запроса, используя:
//Query params are supplied in a Map<String,String>
String baseURL="http://localhost:" + this.port + uri
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseURL);
if (params != null) {
for (final Entry<String, String> entry : params.entrySet()) {
builder.queryParam(entry.getKey(), entry.getValue());
}
}
Это сгенерирует следующее адрес:
http://localhost:8090/remainingAddress?fromDate=2020-07-08T23:54:36.834869+03:00&toDate=2020-07-08T23:54:36.931159+03:00
Проблема в том, что знак «+» не был закодирован и остался таким, каким он изначально присутствовал на карте. На принимающей стороне параметры декодируются, что приводит к следующей дате «020-07-08T23: 54: 36.834869 03:00» (обратите внимание на пробел вместо +), и из-за этого, когда я пытаюсь проанализировать дату с помощью тот же форматировщик не работает.
Я попытался закодировать параметры с помощью java. net .URLEncoder.encode (String, Charset) , прежде чем добавить значение в построитель:
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseURL);
if (params != null) {
for (final Entry<String, String> entry : params.entrySet()) {
var encoded=URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8);
builder.queryParam(entry.getKey(), encoded);
}
}
Однако это вводит "%" как специальный символ, который фактически запускает кодирование в построителе, поэтому параметр даты кодируется 2 раза.
input string: 2020-07-09T00:14:15.230699+03:00
result after first encoding: 2020-07-09T00%3A14%3A15.230699%2B03%3A00
final result: http://localhost:8090/remainingAddress?fromDate=2020-07-09T00%253A14%253A15.230699%252B03%253A00&toDate=2020-07-09T00%253A14%253A15.31158%252B03%253A00
После выполнения запроса я получаю следующий ввод при попытке проанализировать дату: 2020-07-09T00% 253A14% 253A15.230699% 252B03% 253A00 (довольно беспорядок).
Обратите внимание, что в этом проекте используется Spring Boot V2 .5.5.
У меня вопрос, как мне предложить параметры запроса, чтобы они были правильно закодированы? Или, может быть, этот конструктор не предназначен для использования со специальными символами?