Подтвердить что ты не робот

Кодировка URL-адресов Java: URLEncoder против URI

Оглядываясь на веб-страницу W3 Schools URL encoding webpage, он говорит, что @ должен быть закодирован как %40 и что space должен быть закодирован как %20.

Я пробовал как URLEncoder, так и URI, но также не делает это правильно:

import java.net.URI;
import java.net.URLEncoder;

public class Test {
    public static void main(String[] args) throws Exception {

        // Prints me%40home.com (CORRECT)
        System.out.println(URLEncoder.encode("[email protected]", "UTF-8"));

        // Prints Email+Address (WRONG: Should be Email%20Address)
        System.out.println(URLEncoder.encode("Email Address", "UTF-8"));

        // http://www.home.com/test?Email%[email protected]
        // (WRONG: it has not encoded the @ in the email address)
        URI uri = new URI("http", "www.home.com", "/test", "Email [email protected]", null);
        System.out.println(uri.toString());
    }
}

По какой-то причине URLEncoder правильно задает адрес электронной почты, но не пробелы, а URI пробегает валюту, но не адреса электронной почты.

Как я должен кодировать эти 2 параметра, чтобы они соответствовали тому, что говорят w3schools (или это w3schools не так?)

4b9b3361

Ответ 1

Хотя я думаю, что ответ от @fge правильный, поскольку я использовал сторонний веб-сервис, основанный на кодировке, описанной в статье W3C, я последовал за ответом Java эквивалент JavaScript-кода encodingURIComponent, который производит идентичный вывод?

public static String encodeURIComponent(String s) {
    String result;

    try {
        result = URLEncoder.encode(s, "UTF-8")
                .replaceAll("\\+", "%20")
                .replaceAll("\\%21", "!")
                .replaceAll("\\%27", "'")
                .replaceAll("\\%28", "(")
                .replaceAll("\\%29", ")")
                .replaceAll("\\%7E", "~");
    } catch (UnsupportedEncodingException e) {
        result = s;
    }

    return result;
}

Ответ 2

Синтаксис URI определяется RFC 3986 (допустимый контент для строки запроса определен в разделе 3.4). Java URI соответствует этому RFC, с несколькими оговорками, упомянутыми в Javadoc.

Вы заметите, что правило грамматики pchar определяется следующим образом:

pchar = unreserved/pct-encoded/sub-delims/ ":" / "@"

Это означает, что @ юридический в строке запроса.

Trust URI. Он будет делать правильные "юридические" вещи.

Наконец, если вы посмотрите на Javadoc из URLEncoder, вы увидите, что он указывает:

Этот класс содержит статические методы для преобразования String в формат MIME приложения /x -www-form-urlencoded.

Это не то же самое, что строка запроса, определенная спецификацией URI.