openfeign与Ribbon
openfeign
使用
1、因为Ribbon使用时,是直接从controller中导入的,但是这并不是正确的思想
2、因此openfeign在服务调用者
中创建一个service接口,用来接收从controller读取到的数据
3、在自己的controller中调用该service
4、添加注解启动
问题
-
openfeign传数据时,返回结果,即通过return的方式时
-
返回的只能是字符串,json字符串,需要自己再次调整,将其转换成需要的类
-
直接传对象或者集合等是会报错的
具体步骤
- 导包
- 【eureka】【openfeign】
- 提供者与消费者都要导包
- 不知道版本的情况下,官网是有的,但是,我们可以使用,springcloud自动匹配的版本!!!!!
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 服务提供方
- 注意@ResponseBody,不然会被解析到页面上
@Controller
public class ToFinanceAndManager {
@Autowired
StaffCustomsService staffCustomsService;
@RequestMapping("/tofinanceAndManager/{bid}")
@ResponseBody
public List<Customs> getCustoms(@PathVariable("bid") Integer bid){
System.out.println(staffCustomsService.getAllCustoms(bid));
return staffCustomsService.getAllCustoms(bid);
}
}
-
服务消费者
-
接口 value 为提供者服务名,configuration 为配置类 ,后面会提到
-
注意@RequestMapping(“/tofinanceAndManager/{bid}”)要与服务提供者一致
-
@FeignClient(value = "SPRINGCLOUD-STAFF",configuration = CustomizedConfiguration.class) @Service public interface GetFromStaffService { @RequestMapping("/tofinanceAndManager/{bid}") public List<Customs> getCustoms(@PathVariable("bid") Integer bid); }
-
controller
-
@Autowired GetFromStaffService getFromStaffService; @RequestMapping("/finance/queryDetailById/{id}") @ResponseBody public String queryDetail(){ List<Customs> customs = getFromStaffService.getCustoms(id); System.out.println(customs); return "/finance/detail"; }
-
添加注解
- 在启动类上
-
@SpringBootApplication @EnableEurekaClient @EnableFeignClients public class FinanceApplication { public static void main(String[] args) { SpringApplication.run(FinanceApplication.class, args); } }
-
问题解决方案
原创OpenFeign 自定义结果转换_openfeign统一处理返回结果-CSDN博客
添加工具类
- 同意处理返回的参数
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import org.apache.commons.lang.StringUtils;
import feign.codec.Decoder;
import javax.xml.transform.Result;
import java.io.IOException;
import java.lang.reflect.Type;
public class FeignResultDecoder implements Decoder {
@Override
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
if (response.body() == null) {
throw new DecodeException(response.status(), "没有返回有效的数据", response.request());
}
String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
if(StringUtils.isNotEmpty(bodyStr)){
//对结果进行转换
return FeignResultDecoder.json2obj(bodyStr, type);
//可以处理成自己需要返回的类return result;
}
return null;
}
public static <T> T json2obj(String jsonStr, Type targetType) {
try {
JavaType javaType = TypeFactory.defaultInstance().constructType(targetType);
return new ObjectMapper().readValue(jsonStr, javaType);
} catch (IOException e) {
throw new IllegalArgumentException("将JSON转换为对象时发生错误:" + jsonStr, e);
}
}
}
注册到bean
public class CustomizedConfiguration {
@Bean
public Decoder feignDecoder() {
return new FeignResultDecoder();
}
}