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

Spring RestTemplate:如何让fromUriString保留URL中的#字符

解决RestTemplate传递含#字符密码被截断的问题

这个问题我之前也碰到过,核心原因是**#在URI规范里是片段标识符的起始字符**,默认的URI解析逻辑会把#后面的内容当成页面内锚点,不会作为请求参数的一部分发送给服务器,自然就被"丢弃"了。下面给你几个靠谱的解决办法:

方法一:用UriComponentsBuilder构建编码后的URI

这是最推荐的方式,Spring提供的UriComponentsBuilder会自动帮你处理参数编码,完全不用手动操心:

import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class RestTemplateExample {
    public static void main(String[] args) {
        String password = "myPass#123";
        // 构建URI组件,自动编码参数
        UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("http://your-server.com/api/auth")
                .queryParam("username", "testUser")
                .queryParam("password", password)
                .build(true); // 传入true表示对所有组件进行URL编码

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(uriComponents.toUri(), String.class);
    }
}

这里的build(true)是关键,它会把密码里的#转换成%23,这样服务器就能正确解析到完整的密码字符串。

方法二:手动编码密码参数

如果你习惯直接拼接URL,可以用Spring的UriUtils工具类手动编码密码部分(别用Java自带的URLEncoder,它的编码规则和URI规范不完全一致):

import org.springframework.web.util.UriUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;

public class RestTemplateManualEncode {
    public static void main(String[] args) {
        String password = "myPass#123";
        // 手动编码密码,指定UTF-8字符集
        String encodedPassword = UriUtils.encode(password, StandardCharsets.UTF_8.name());
        // 拼接成完整URL
        String url = String.format("http://your-server.com/api/auth?username=testUser&password=%s", encodedPassword);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
    }
}

为什么不能直接让fromUriString保留#?

这里要澄清一个误区:原始的#字符根本不应该出现在查询参数里。根据URI规范,#是保留字符,专门用来标识片段,如果你不编码直接传递,HTTP客户端(包括RestTemplate)会自动把#后面的内容从请求URL中剥离,服务器永远接收不到这部分内容。所以正确的做法是编码,而不是强制保留原始的#。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:03:19