You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

URLDecoder解码丢失加号问题:求保留加号的解码方案

解决URLDecoder解码时加号被替换为空格的问题

当文件名abc你好+在Content-Disposition头中被编码为abc%E4%BD%A0%E5%A5%BD+时,用java.net.URLDecoder.decode()解码会把加号替换成空格,导致结果和原文件名不符。下面提供几种解决方法,既能解码百分号编码,又能保留加号:

方法一:手动处理(无需第三方包)

URLDecoder的解码逻辑遵循application/x-www-form-urlencoded规范,默认会把加号转成空格。要保留加号,有两种简单的手动处理方式:

方式1:预处理替换加号

解码前先把字符串中的+替换成它的百分号编码形式%2B,再用URLDecoder解码:

import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

public class FileNameDecodeExample {
    public static void main(String[] args) {
        String encodedFileName = "abc%E4%BD%A0%E5%A5%BD+";
        // 先将+替换为%2B
        String preprocessed = encodedFileName.replace("+", "%2B");
        String decoded = URLDecoder.decode(preprocessed, StandardCharsets.UTF_8.name());
        System.out.println(decoded); // 输出: abc你好+
    }
}

方式2:自定义百分号解码逻辑

自己实现只处理%XX格式编码的方法,直接忽略加号,保留原字符:

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class CustomDecoder {
    public static String decodePercentOnly(String encoded, Charset charset) {
        StringBuilder result = new StringBuilder();
        int len = encoded.length();
        int i = 0;
        while (i < len) {
            char c = encoded.charAt(i);
            if (c == '%' && i + 2 < len) {
                // 解析%XX格式的十六进制编码
                String hex = encoded.substring(i + 1, i + 3);
                try {
                    byte[] byteArr = {(byte) Integer.parseInt(hex, 16)};
                    result.append(new String(byteArr, charset));
                    i += 3;
                } catch (NumberFormatException e) {
                    // 无效的百分号编码,直接保留原字符
                    result.append(c);
                    i++;
                }
            } else {
                // 非百分号编码字符,直接追加
                result.append(c);
                i++;
            }
        }
        return result.toString();
    }

    public static void main(String[] args) {
        String encodedFileName = "abc%E4%BD%A0%E5%A5%BD+";
        String decoded = decodePercentOnly(encodedFileName, StandardCharsets.UTF_8);
        System.out.println(decoded); // 输出: abc你好+
    }
}

方法二:使用第三方库(Apache Commons Codec)

Apache Commons Codec库的URLCodec提供了更灵活的解码控制,可以关闭加号替换为空格的行为:

代码示例

import org.apache.commons.codec.net.URLCodec;
import java.nio.charset.StandardCharsets;

public class CommonsCodecExample {
    public static void main(String[] args) throws Exception {
        URLCodec codec = new URLCodec();
        // 设置解码时不将+替换为空格
        codec.setEncodeChar('+');
        String encodedFileName = "abc%E4%BD%A0%E5%A5%BD+";
        String decoded = codec.decode(encodedFileName, StandardCharsets.UTF_8.name());
        System.out.println(decoded); // 输出: abc你好+
    }
}

依赖引入(Maven)

如果用Maven管理项目,需要在pom.xml中添加依赖:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version> <!-- 建议使用最新稳定版本 -->
</dependency>

内容的提问来源于stack exchange,提问作者varen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:30:36