feign远程调用无法传递对象属性
1、get请求405错误
通过查看feign底层源码,feign底层使用的是httpurlconnection
的工具,而进行传递body的时候,会调用getOutputStrean
方法,里边会判断是否是get请求,如果是get请求,则自动转为post
请求,而远方的服务只能够支持get
请求,因此会报错
2、使用feign请求远端,configuration
添加如下配置类
package com.zx.consumer;
import com.google.common.collect.Lists;
import feign.Contract;
import feign.MethodMetadata;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.annotation.PathVariableParameterProcessor;
import org.springframework.cloud.openfeign.annotation.RequestHeaderParameterProcessor;
import org.springframework.cloud.openfeign.annotation.RequestParamParameterProcessor;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.List;
/**
* @author: zhaoxu
* @date: 2021/4/29 0:20
*/
@Configuration
public class FeignConfiguration implements RequestInterceptor, AnnotatedParameterProcessor {
@Override
public void apply(RequestTemplate template) {
//开启线程共享
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 对消息头进行配置
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
template.header(name, values);
}
}
}
@Resource
private ConversionService feignConversionService;
private static final Class<RequestBody> ANNOTATION = RequestBody.class;
@Override
public Class<? extends Annotation> getAnnotationType() {
return ANNOTATION;
}
@Override
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
int paramIndex = context.getParameterIndex();
MethodMetadata metadata = context.getMethodMetadata();
if (metadata.queryMapIndex() == null) {
metadata.queryMapIndex(paramIndex);
metadata.queryMapEncoded(true);
}
if ("GET".equals(metadata.template().method())) {
return true;
}
return false;
}
@Bean
public Contract feignContract() {
List<AnnotatedParameterProcessor> parameterProcessors = Lists.newArrayList();
parameterProcessors.add(new PathVariableParameterProcessor());
parameterProcessors.add(new RequestHeaderParameterProcessor());
parameterProcessors.add(new RequestParamParameterProcessor());
parameterProcessors.add(new FeignConfiguration());
return new SpringMvcContract(parameterProcessors, feignConversionService);
}
}