序言

这次遇到的问题,是使用Feign调用远程服务时报错,

报错日志及相关图片

// A code block
feign.FeignException$BadRequest: [400 ] during [GET] to [http://调用服务/接口路径] [调用类#接口()]: [<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;... (435 bytes)]
	at feign.FeignException.clientErrorStatus(FeignException.java:195)
	at feign.FeignException.errorStatus(FeignException.java:177)
	at feign.FeignException.errorStatus(FeignException.java:169)
	at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92)
	at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
	at com.sun.proxy.$Proxy174.getAllLine(Unknown Source)

后端报错图
后端报错图
前端报错图
前端报错图

报错原因

原因大体是这样的:A服务调用B服务接口,A服务接口为post,B服务接口为get,post请求存在body请求体时,header会带上以下参数:
// A code block
content-type:application/json

解决办法

原因就是 header 携带了 post请求体中的全部参数 ,解决就是使用 feign过滤器对 header进行过滤,只保留自己所需要的参数即可。

对应代码

// An highlighted block
@Configuration
public class FeginInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
       try {
           Map<String,String> headers = getHeaders();
           for(String headerName : headers.keySet()){
               //requestTemplate.header(headerName, headers.get(headerName));
               //此处加入过滤,即可解决报错
               if (checkEssential(headerName)) {
                   requestTemplate.header(headerName, headers.get(headerName));
               }

           }

       }catch (Exception e){
           e.printStackTrace();
       }
    }

    private Map<String, String> getHeaders(){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 请求头必要传递参数过滤,只携带必要请求头信息
     * @param name
     * @return
     */
    private boolean checkEssential(String name) {
        ArrayList<String> headers = Lists.newArrayList("Authorization");
        return headers.stream().anyMatch(e -> e.equalsIgnoreCase(name));
    }
 
}

下面是附带feign 更改前代码对应图:
更改前

结语

不是职业博主,只是记录自己用到的一些技术点或者问题相关的解决办法,以便于以后用到的时候查看,顺便分享。

参考链接

> https://blog.csdn.net/u011504708/article/details/121315814

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐