【问题标题】:Url encoding issue with url connectionurl 连接的 URL 编码问题
【发布时间】:2026-01-21 18:40:01
【问题描述】:

请帮我编码网址:

http://dsxsd.com/def/fss/default/files/10 رسم الصباح - 1.mp3

我需要在安卓应用中下载这个文件。 当我试图建立 url 连接时,它给了我 404。但在浏览器上,url 正在工作。 当我粘贴浏览器编码的网址时,它工作正常。

但我不能硬核这些东西,因为我有这样的网址来自服务器。

我尝试使用 Urlencoder.encode(url,"UTF-8"); 进行编码 但是服务器调用给了我错误的 url 我得到“java.net.MalformedURLException: Protocol not found: http%3A%2F%........

让这个 url 不将路径参数和查询参数分开来单独编码。

请帮帮我。

【问题讨论】:

    标签: java android url encoding utf-8


    【解决方案1】:

    使用URI templatesURLEncoder.encode() 不起作用。

    上面库的使用:

    final URITemplate template = new URITemplate("http://dsxsd.com/def/" +
        "fss/default/files/{filename}");
    
    final VariableMap vars = VariableMap.newBuilder()
        .addScalarValue("filename", "10 رسم الصباح - 1.mp3")
        .freeze();
    
    System.out.println(template.toString(vars));
    

    输出:

    http://dsxsd.com/def/fss/default/files/10%20%D8%B1%D8%B3%D9%85%20%D8%A7%D9%84%D8%B5%D8%A8%D8%A7%D8%AD%20-%201.mp3
    

    【讨论】:

    • 对于这个特定的示例,您的库无法实现使用 URLEncoder 无法实现的任何功能。
    • 同意但是,图书馆看起来很有希望。除了 Gradle 构建之外,我不能得到一个简单的项目吗?不使用 Gradle 的人很难配置它。
    • @Rajivyadav 为什么要克隆这个项目?只需使用 gradle/maven 工件
    • 对不起,我得到了。生成最终存档时出错:找到 APK 的重复文件:ASL-2.0.txt 来源 1:/home/user/.gradle/caches/modules-2/files-2.1/com.github.fge/jackson-coreutils/1.5/5108553833b399fed6a1f7f979b89a07b786d3c2 /jackson-coreutils-1.5.jar 来源 2:/home/user/.gradle/caches/modules-2/files-2.1/com.github.fge/btf/1.1/597aaacc063dcf8b77c17729706b895c562b162e/btf-1.1.jar
    • @Rajivyadav 看起来像一个错误...你能在 github 中打开一个错误吗?尤其要描述您的构建环境(例如 APK 是什么?)
    【解决方案2】:

    问题是你正在编码整个 URL,你只需要编码文件名,例如

    String filename = Uri.encode("10 رسم الصباح - 1.mp3");
    String url = "http://dsxsd.com/def/fss/default/files/" + filename;
    

    【讨论】:

    • 我正在从服务器获取此 url。我没有在本地配置它。顺便说一句,我尝试对其进行子字符串化并对其进行编码,它正在返回dsxsd.com/def/fss/default/files/…,这不是一个正确的网址。
    • 在这种情况下,您可以拆分 URL 并仅对该路径的最后一部分进行编码。
    • 这对我没有帮助。空格会产生问题。
    • @Philio 不,它不会..."+" 不是有效的正则表达式...您可能是指.replace(),即使这样URLEncoder 编码的字符集也不是与 URI 路径段所要求的设置相同;有关更多详细信息,请参阅我链接到的项目的自述文件...
    • 没错,它需要被转义。但是,无论如何, Uri.encode 是一个更好的解决方案,因为它可以正确编码空格。解决方案已更新。
    【解决方案3】:

    如果你只有网址,请使用此方法

    private String encodeUrl(String link) throws UnsupportedEncodingException {
        Uri uri = (Uri.parse(link));
        String result = null;
        if (Objects.equals(uri.getScheme(), "content")) {
            try (Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
                if (cursor != null && cursor.moveToFirst()) {
                    result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                }
            }
        }
        if (result == null) {
            result = uri.getPath();
            int cut = Objects.requireNonNull(result).lastIndexOf('/');
            if (cut != -1) {
                result = result.substring(cut + 1);
            }
        }
        return link.replace(result
                ,URLEncoder.encode(result, "UTF-8")
                        .replace("+", "%20"));
    }
    

    【讨论】: