在 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的执行造成任何问题,不过可以通过修改代码来解决