手机大师 發表於 2026-1-13 09:31:09

解决openfeign调用时content-type的问题

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>问题1描述</li><ul class="second_class_ul"><li>原因分析</li><li>所以这个时候就有一个解决办法</li></ul><li>问题2描述</li><ul class="second_class_ul"><li>解决方法</li></ul><li>问题3</li><ul class="second_class_ul"><li>测试结果</li><li>解决办法</li></ul><li>总结</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>问题1描述</h2>
<p>今天在A服务使用openfeign调用B服务的时候,发现经常会偶发性报错。</p>
<p>错误如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250761.jpg" /></p>
<p>情况为偶发,很让人头疼。</p>
<p>两个接口如下:&nbsp;</p>
<p><strong>A服务接口:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250743.jpg" /></p>
<p><code>delayReasonApi.test(student);</code>就是使用openfeign调用B服务的接口。&nbsp;</p>
<p><strong>B服务接口:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250747.jpg" /></p>
<p class="maodian"></p><h3>原因分析</h3>
<p>因为A服务的接口是一个文件上传的接口,所以前端请求头中使用的是multipart/form-data 来请求的该接口。而B服务的接口是一个用json接口参数的接口,所以需要请求头中的Content-Type为application/json。</p>
<p>如果在上面都没有配置过的情况下,在B服务的接口参数使用@RequestBody注解来接受的时候,openfeign是会默认使用application/json 的content-type来进行请求的。</p>
<p>代码如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250720.jpg" /></p>
<p>但是一般我们都会在项目中加上openfeign的配置文件,将目前的所有的header中的参数全部写入openfeign的请求中,如下:</p>
<div class="jb51code"><pre class="brush:java;">@Component
public class FeignConfiguration implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
      ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
      if (attributes != null) {
            HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
            Enumeration&lt;String&gt; headerNames = request.getHeaderNames();
            if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                  String name = headerNames.nextElement();
                  String values = request.getHeader(name);
                  template.header(name, values);
                }
            }
      }
    }
}
</pre></div>
<p>这样就导致,我A服务接口使用的是multipart/form-data,而B服务接口需要的是application/json,而我的配置类会把A接口的multipart/form-data写到请求头中,这样就会导致openfeign在请求的时候会有两个content-Type,而且这两个值的顺序是不一定的,有的时候application/json在前面,有的时候multipart/form-data在前面:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250782.jpg" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250772.jpg" /></p>
<p>我估计B服务在拿的时候只那集合中的第一个,但是我没找源码嘿嘿。当multipart/form-data在前面的时候,就会报上面的错误。</p>
<p class="maodian"></p><h3>所以这个时候就有一个解决办法</h3>
<p>把我们的配置类中的代码进行修改,跳过content-type的赋值。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250763.jpg" /></p>
<p>如此,openfeign就只会用默认的application/json进行请求了。</p>
<p class="maodian"></p><h2>问题2描述</h2>
<p>延续上面的问题,当我修改了配置类之后,发现还是会有这样的情况,后来发现是我们的微服务的项目中有两个服务都写了openfeign的配置类,而这两个配置类都被引用在了A服务中。</p>
<p>openfeign在调用接口的时候会先迭代所有的配置类,导致前面的情况又重演了一遍。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250732.jpg" /></p>
<p class="maodian"></p><h3>解决方法</h3>
<p>删掉一个配置类。</p>
<p class="maodian"></p><h2>问题3</h2>
<p>继续上面的情况,如果B服务的接口也是个文件上传接口,那么这个时候也是需要使用multipart/form-data的,那这个时候需要怎么做呢?openfeign是否会默认使用multipart/form-data呢?&nbsp;</p>
<p><strong>B接口如下:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250739.jpg" /></p>
<p class="maodian"></p><h3>测试结果</h3>
<p>content-type为空,并且会报错</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250773.jpg" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250739.jpg" /></p>
<p class="maodian"></p><h3>解决办法</h3>
<p>在B接口上加上 consumes = &ldquo;multipart/form-data&rdquo;</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250783.jpg" /></p>
<p>此时content-type就有值了。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011309250733.jpg" /></p>
<p>end!!!</p>
<p class="maodian"></p><h2>总结</h2>
<p>以上为个人经验,希望能给大家一个参考,也希望大家多多支持琼殿技术社区。&nbsp;</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>SpringBoot项目整合OpenFeign启动失败及运行时常见错误解决方案</li><li>SpringCloud&nbsp;&nbsp;OpenFeign的使用举例详解</li><li>openfeign使用nacos服务注册方式调用的实现</li><li>springcloud&nbsp;openFeign客户端禁用SSL验证</li><li>Spring&nbsp;Cloud&nbsp;OpenFeign实现动态服务名调用的示例代码</li><li>SpringBoot整合OpenFeign的完整指南</li><li>Spring&nbsp;Cloud之远程调用OpenFeign参数传递</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 解决openfeign调用时content-type的问题