黄金列车 發表於 2026-1-13 10:56:23

RestTemplate发送Post请求报错:414 URI Too Long问题及解决

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>一、报错背景</li><li>二、问题分析:414 URI Too Long</li><ul class="second_class_ul"><li>2.1、常见原因</li></ul><li>三、解决方法</li><ul class="second_class_ul"><li>3.1、使用 LinkedMultiValueMap 处理表单数据(推荐)</li><li>3.2、将参数拼接到URI上</li></ul><li>四、避免误区</li><ul class="second_class_ul"></ul><li>五、总结</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>一、报错背景</h2>
<p>使用RestTemplate发送http Post请求时,返回了一个报错 414 URI Too Long。</p>
<p>因为服务端是Post请求并用@RequestParam进行接收,所以我将参数都拼接在URL后面,如http://localhost:80/add?name=1&amp;age=2 ,导致URL过长。</p>
<p><strong>报错代码</strong></p>
<div class="jb51code"><pre class="brush:java;">RestTemplate restTemplate = new RestTemplate();

// 创建请求体
List&lt;NameValuePair&gt; params = new ArraysList&lt;&gt;();
params.add(new BasicNameValuePair("name","张三"));
params.add(new BasicNameValuePair("age","15"));
//....... 设置大量内容

// 设置请求头
HttpHeaders headers = new HttpHeaders();

// 创建HttpEntity对象
HttpEntity&lt;String&gt; httpEntity = new HttpEntity&lt;&gt;(null,headers);
URI uri = URI.create(url);
if(!CollectionUtils.isEmpty(params)){
        String param = URLEncodedUtils.format(params, StandardCharsets.UTF_8);
        uri = URI.create(url+"?"+param);
}
// 发送POST请求
String response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity , String.class).getBody();
</pre></div>
<p><strong>报错内容</strong></p>
<blockquote><p>org.springframework.web.client.HttpClientErrorException : 414 URI Too Long:&quot;&lt;h1&gt;Bad Message 414&lt;/h1&gt;&lt;pre&gt;reason: URI Too Long&lt;/pre&gt;&quot;​</p></blockquote>
<p class="maodian"></p><h2>二、问题分析:414 URI Too Long</h2>
<p>HTTP状态码414表示客户端发送的请求URI过长,服务器拒绝处理。使用RestTemplate发送POST请求时出现该错误,通常是因为请求参数被错误地附加到URL中而非请求体中,导致URL超过服务器限制长度。</p>
<p>HTTP协议规定,请求的URI长度不能超过2083个字符。这是因为在HTTP/1.1协议中,请求行和请求头字段的总长度被限制在8192字节(不包括CRLF)。</p>
<p class="maodian"></p><h3>2.1、常见原因</h3>
<ul><li><strong>参数误放在URL中</strong>:POST请求本应将参数放在请求体(Body)中,但实际被拼接到了URL末尾。</li><li><strong>RestTemplate配置问题</strong>:未正确配置<code>HttpMessageConverter</code>,导致参数无法序列化到请求体。</li><li><strong>URL编码问题</strong>:参数中包含特殊字符未编码,进一步增加URL长度。</li></ul>
<p class="maodian"></p><h2>三、解决方法</h2>
<p>本文报错是由于发送Post请求时,服务端的接口用的是@RequestParam接收参数,而不是json,所以以下整理几种方法发送@RequestParam入参类型的POST请求。</p>
<p class="maodian"></p><h3>3.1、使用 LinkedMultiValueMap 处理表单数据(推荐)</h3>
<p>本方法是将请求参数放到请求体中,不占用URI的长度,所以就算请求体比较大,也不会报414 URI Too Long的错误。</p>
<p>示例:</p>
<div class="jb51code"><pre class="brush:java;">RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
// 设置内容类型为 application/x-www-form-urlencoded
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

// 使用 MultiValueMap 存放表单数据
MultiValueMap&lt;String, String&gt; formData = new LinkedMultiValueMap&lt;&gt;();
formData.add("key1", "value1");
formData.add("key2", "value2");
// ... 可以添加很多对,只要不超出服务器对Body大小的通常宽松限制

HttpEntity&lt;MultiValueMap&lt;String, String&gt;&gt; requestEntity = new HttpEntity&lt;&gt;(formData, headers);

ResponseEntity&lt;String&gt; response = restTemplate.postForEntity(
    "http://your-api-endpoint.com/api/resource",
    requestEntity,
    String.class
);
</pre></div>
<p class="maodian"></p><h3>3.2、将参数拼接到URI上</h3>
<p>如果你只是想在URL中包含查询参数,可以使用Uri来构建URL。</p>
<div class="jb51code"><pre class="brush:java;">RestTemplate restTemplate = new RestTemplate();

// 创建请求体
List&lt;NameValuePair&gt; params = new ArraysList&lt;&gt;();
params.add(new BasicNameValuePair("name","张三"));
params.add(new BasicNameValuePair("age","15"));
//....... 设置大量内容

// 设置请求头
HttpHeaders headers = new HttpHeaders();

// 创建HttpEntity对象
HttpEntity&lt;String&gt; httpEntity = new HttpEntity&lt;&gt;(null,headers);
URI uri = URI.create(url);
if(!CollectionUtils.isEmpty(params)){
        String param = URLEncodedUtils.format(params, StandardCharsets.UTF_8);
        uri = URI.create(url+"?"+param);
}
// 发送POST请求
String response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity , String.class).getBody();
</pre></div>
<p class="maodian"></p><h2>四、避免误区</h2>
<ul><li>不要使用RestTemplate的getForObject发送 POST 请求(GET 请求参数只能在 URL 中,本身就容易触发 414)。</li><li>即使是 POST 请求,若通过url + &ldquo;?key=&rdquo; + value拼接参数,本质仍是将参数放在 URL 中,会导致同样的错误。</li><li>若接口必须要求参数在 URL 中(不符合 POST 规范,但某些旧接口可能如此),则需要缩短参数长度,或联系服务器端放宽 URL 长度限制(不推荐,因为 URL 长度本身有协议限制)。</li></ul>
<p class="maodian"></p><h2>五、总结</h2>
<p>以上为个人经验,希望能给大家一个参考,也希望大家多多支持琼殿技术社区。</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Java&nbsp;RestTemplate&nbsp;post请求参数问题及解决</li><li>RestTemplate().postForEntity的参数使用及说明</li><li>使用restTemplate.postForEntity()的问题</li><li>RestTemplate如何使用JSON发送Post请求</li><li>RestTemplate报错I/O error on POST request for的解决办法</li><li>restTemplate发送get与post请求并且带参数问题</li><li>RestTemplate调用POST和GET请求示例详解</li><li>RestTemplate发送HTTP POST请求使用方法详解</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: RestTemplate发送Post请求报错:414 URI Too Long问题及解决