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

Spring Boot 2.5中RestTemplate发送application/x-www-form-urlencoded请求时因Content-Type含charset报错的问题排查

解决RestTemplate发送application/x-www-form-urlencoded请求的Content-Type报错问题

我之前也碰到过一模一样的情况——目标接口对Content-Type的校验特别严格,只接受纯application/x-www-form-urlencoded,不允许携带;charset=utf-8后缀。下面是几个经过验证的可行方案:

方案1:直接设置Content-Type字符串(最简单)

Spring的MediaType.APPLICATION_FORM_URLENCODED常量默认会附加;charset=utf-8,所以我们可以跳过这个常量,直接手动设置纯字符串形式的Content-Type:

public HttpHeaders getHeaders(){
    HttpHeaders headers = new HttpHeaders();
    // 直接指定纯Content-Type字符串,避免自动添加charset
    headers.set("Content-Type", "application/x-www-form-urlencoded");
    headers.add("header1", "aaa");
    return headers;
}

方案2:自定义不带charset的MediaType实例

如果更倾向于使用MediaType对象,可以创建一个不包含字符集的实例:

public HttpHeaders getHeaders(){
    HttpHeaders headers = new HttpHeaders();
    // 构建不带charset的application/x-www-form-urlencoded类型
    MediaType formMediaType = new MediaType("application", "x-www-form-urlencoded");
    headers.setContentType(formMediaType);
    headers.add("header1", "aaa");
    return headers;
}

方案3:通过请求拦截器统一修改Content-Type

如果需要在多个请求中统一处理这种情况,可以给RestTemplate添加一个拦截器,自动移除Content-Type中的charset后缀:

public void getToken(){ 
    RestTemplate restTemplate = new RestTemplate();
    
    // 添加请求拦截器,修正Content-Type格式
    restTemplate.getInterceptors().add((request, body, execution) -> {
        HttpHeaders headers = request.getHeaders();
        MediaType contentType = headers.getContentType();
        if (contentType != null && contentType.toString().contains("charset=utf-8")) {
            // 替换为纯application/x-www-form-urlencoded
            headers.set("Content-Type", "application/x-www-form-urlencoded");
        }
        return execution.execute(request, body);
    });
    
    ResponseEntity<TokenResponseDTO> responses = restTemplate 
        .postForEntity(url, new HttpEntity<>(getForm(), getHeaders()), TokenResponseDTO.class); 
    log.info(responses.toString()); 
}

问题根源

Spring中MediaType.APPLICATION_FORM_URLENCODED的定义是application/x-www-form-urlencoded;charset=UTF-8,当你调用headers.setContentType()时,会把这个完整的字符串设置到请求头里。而有些接口的校验逻辑是精确匹配Content-Type值,不允许有额外的参数,因此就会返回"endpoint only accepts application/x-www-form-urlencoded for POST requests"的错误。

内容的提问来源于stack exchange,提问作者W. Silva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:12:31