在 java 中对字符串 url 中的查询参数值进行编码 &
Encode & in query parameter value in string url in java
我有像这样获取字符串 url 的函数
String url = http://www.example.com/site?a=abc&b=qwe & asd
此处“qwe & asd”为单个查询值
我希望这个 url 被编码成
URI url = http://www.example.com/site?a=abc&b=qwe%20%26%20asd"
我尝试了各种方法,但我无法在“qwe & asd”中对 & 进行编码,space 被编码为 %20,但 & 没有被编码为 %26。
该函数仅以字符串格式获取 url 并完成 url,我无权了解它是如何传递给函数的。
符号可以是任意符号,大多数情况下是&,取值场景相似的参数可以有多个
您可以使用 URL编码器对您的 URL 进行编码,例如:
URLEncoder.encode(value, StandardCharsets.UTF_8.toString())
结果将是:
http://www.example.com/site?a=abc&b=qwe+%26+asd
URL 编码通常用加号 (+) 或 %20 替换 space。您可以使用此代码对 url 进行编码:
@SneakyThrows
private String encodeValue(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
}
@Test
void urlEncodingTest(){
Map<String, String> requestParams = new HashMap<>();
requestParams.put("a", "abc");
requestParams.put("b", "qwe & asd");
String encodedURL = requestParams.keySet().stream()
.map(key -> key + "=" + encodeValue(requestParams.get(key)))
.collect(joining("&", "http://www.example.com/site?", ""));
}
如果您需要更多详细信息,可以查看此 link
这是我解决问题的方法
private URI convertStringURLToURI(String url) {
URI uri = null;
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(url);
String queryParameter = uriComponentsBuilder.build().toUri().getQuery();
if(queryParameter != null) {
// Split the query part into queries
String[] splitedQueryParameter = queryParameter.split("&");
Stack<String> queryParamStack = new Stack<>();
for(int i = 0; i < splitedQueryParameter.length; i++) {
/*
In case "&" is present in any of the query values ex. b=abc & xyz then
it would have split as "b=abc" and "xyz" due to "&" symbol
Below code handle such situation
If "=" is present in any value then it is pushed to stack,
else "=" is not present then this value was part of the previous push query
due to "&" present in query value, so the else part handles this situation
*/
if(splitedQueryParameter[i].contains("=")) {
queryParamStack.push(splitedQueryParameter[i]);
} else {
String oldValue = queryParamStack.pop();
String newValue = oldValue + "&" + splitedQueryParameter[i];
queryParamStack.push(newValue);
}
}
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
while(!queryParamStack.isEmpty()) {
String[] query = queryParamStack.pop().split("=");
String queryParameterValue = query[1];
/*
If in the query value, "=" is present somewhere then the query value would have
split into more than two parts, so below for loop handles that situation
*/
for(int i = 2; i < query.length; i++) {
queryParameterValue = queryParameterValue + "=" + query[i];
}
// encoding the query value and adding to Map
queryParams.add(query[0], UriUtils.encode(queryParameterValue, "UTF-8"));
}
uriComponentsBuilder.replaceQueryParams(queryParams);
try {
uri = new URI(uriComponentsBuilder.build().toString());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return uri;
}
所以,这个字符串 URL
String url = "http://www.example.com/site?a=abc&b=qwe & asd&c=foo ?bar=2";
变成
URI uri = "http://www.example.com/site?c=foo%20%3Fbar%3D2&b=qwe%20%26%20asd&a=abc"
这里由于使用了Stack,query的顺序发生了变化,不会对uri的执行造成任何问题,不过可以通过修改代码来解决
我有像这样获取字符串 url 的函数
String url = http://www.example.com/site?a=abc&b=qwe & asd
此处“qwe & asd”为单个查询值
我希望这个 url 被编码成
URI url = http://www.example.com/site?a=abc&b=qwe%20%26%20asd"
我尝试了各种方法,但我无法在“qwe & asd”中对 & 进行编码,space 被编码为 %20,但 & 没有被编码为 %26。
该函数仅以字符串格式获取 url 并完成 url,我无权了解它是如何传递给函数的。
符号可以是任意符号,大多数情况下是&,取值场景相似的参数可以有多个
您可以使用 URL编码器对您的 URL 进行编码,例如:
URLEncoder.encode(value, StandardCharsets.UTF_8.toString())
结果将是:
http://www.example.com/site?a=abc&b=qwe+%26+asd
URL 编码通常用加号 (+) 或 %20 替换 space。您可以使用此代码对 url 进行编码:
@SneakyThrows
private String encodeValue(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
}
@Test
void urlEncodingTest(){
Map<String, String> requestParams = new HashMap<>();
requestParams.put("a", "abc");
requestParams.put("b", "qwe & asd");
String encodedURL = requestParams.keySet().stream()
.map(key -> key + "=" + encodeValue(requestParams.get(key)))
.collect(joining("&", "http://www.example.com/site?", ""));
}
如果您需要更多详细信息,可以查看此 link
这是我解决问题的方法
private URI convertStringURLToURI(String url) {
URI uri = null;
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(url);
String queryParameter = uriComponentsBuilder.build().toUri().getQuery();
if(queryParameter != null) {
// Split the query part into queries
String[] splitedQueryParameter = queryParameter.split("&");
Stack<String> queryParamStack = new Stack<>();
for(int i = 0; i < splitedQueryParameter.length; i++) {
/*
In case "&" is present in any of the query values ex. b=abc & xyz then
it would have split as "b=abc" and "xyz" due to "&" symbol
Below code handle such situation
If "=" is present in any value then it is pushed to stack,
else "=" is not present then this value was part of the previous push query
due to "&" present in query value, so the else part handles this situation
*/
if(splitedQueryParameter[i].contains("=")) {
queryParamStack.push(splitedQueryParameter[i]);
} else {
String oldValue = queryParamStack.pop();
String newValue = oldValue + "&" + splitedQueryParameter[i];
queryParamStack.push(newValue);
}
}
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
while(!queryParamStack.isEmpty()) {
String[] query = queryParamStack.pop().split("=");
String queryParameterValue = query[1];
/*
If in the query value, "=" is present somewhere then the query value would have
split into more than two parts, so below for loop handles that situation
*/
for(int i = 2; i < query.length; i++) {
queryParameterValue = queryParameterValue + "=" + query[i];
}
// encoding the query value and adding to Map
queryParams.add(query[0], UriUtils.encode(queryParameterValue, "UTF-8"));
}
uriComponentsBuilder.replaceQueryParams(queryParams);
try {
uri = new URI(uriComponentsBuilder.build().toString());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return uri;
}
所以,这个字符串 URL
String url = "http://www.example.com/site?a=abc&b=qwe & asd&c=foo ?bar=2";
变成
URI uri = "http://www.example.com/site?c=foo%20%3Fbar%3D2&b=qwe%20%26%20asd&a=abc"
这里由于使用了Stack,query的顺序发生了变化,不会对uri的执行造成任何问题,不过可以通过修改代码来解决