场景:springboot项目中,涉及到访问其他模块的开放接口(类似于访问第三方接口)的情况。
第一时间反应就是使用 httpclient 进行请求,随后又了解到 RestTemplate,feign。
HttpClient 是 apache 的开源
RestTemplate 是Spring的封装
Feign 是 RestTemplate的进一步分装
使用过springcloud的应该都了解,Feign更加简洁。
Feign的使用--------------------------start---------------------------------------
springboot项目 pom.xml 引入 feign依赖:
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-core</artifactId>
<version>8.18.0</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-jackson</artifactId>
<version>8.18.0</version>
</dependency>
java代码使用:
1、建立feignClient的接口
public interface TestFeignClient{
/**
* 添加学生
*/
@RequestLine("POST /api/student/addStudent")
@Headers({"Content-Type: application/json"})
Object addStudent(@RequestBody Object object);
/**
* 通过名字查询学生
*/
@RequestLine("GET /api/selectStudentByName")
Object selectStudentByName(@QueryMap Map<Object, Object> queryMap);
}
2、创建FeignClient的配置类
@Configuration
public class ApiFeignConfig {
/**
* 请求地址 从yml文件读取
* localhost:8888
*/
@Value("${api.feign.url}")
private String url;
/**
* TestFeignClient 配置
* @return
*/
@Bean
TestFeignClient testFeignClient(){
return Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
//超时时间
.options(new Request.Options(60000, 60000))
//重试机制
.retryer(new Retryer.Default(5000, 5000, 3))
.target(TestFeignClient.class, url);
}
}
3、Controller中使用
@RestController
@RequestMapping("/feign")
public class ApiController {
@Autowired
private TestFeignClient testFeignClient ;
/**
* 请求外部接口 通过名字获取学生信息
* @param username
* @return
*/
@RequestMapping("/selectStudentByName")
public Object selectStudentByName(@RequestParam(value = "username") String username){
Map<Object, Object> map = new HashMap<>();
map.put("username",username);
Object object = testFeignClient.selectStudentByName(map);
return object;
}
/**
* 请求外部接口 添加学生
* map 接收 json 参数
* @param map
* @return
*/
@PostMapping("/student/addStudent")
public Object addStudent(@RequestBody Student student){
Object object = testFeignClient.addStudent(student);
return object;
}
}
上述是自己的项目,例如:localhost:8080
api.feign.url 是要请求的接口地址,例如:localhost:8888
它的接口就比如:
@RestController
@RequestMapping("/api")
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping("/selectStudentByName")
public Object selectStudentByName(@RequestParam(value = "username") String username){
//查询学生的业务处理
Student stu = studentService.selectStudentByName(username);
return stu ;
}
@PostMapping("/student/addStudent")
public Object addStudent(@RequestBody Student student ){
return studentService.addStudent(student);
}
}
它的访问接口就是:
localhost:8888/api/student/addStudent 添加学生
localhost:8888/api/selectStudentByName 查询学生
测试:
请求接口 localhost:8080/feign/student/addStudent、localhost:8080/feign/selectStudentByName
通过feign 转发请求到 localhost:8888/student/addStudent localhost:8888/selectStudentByName
返回数据
至此结束----------------------------------end-----------------------------------------------
注意的点:
再此举例 post 与 get 请求,@Headers 可以按照自己使用场景设置需要的值。
TestFeignClient 类的请求参数问题:
@QueryMap (说出来大家可能不信,这个的用法我是猜出来的)
我在使用的时候,在请求参数上遇到了一些问题,大部分接口有以下几种:
get 请求,参数在url显示,此时使用就使用 @QueryMap 构建k-v 的map集合,@RequestParam 可以接收到
Object selectStudentByName(@QueryMap Map<Object, Object> queryMap);
post 请求,大部分是json格式的请求数据,此时也简单,我们使用 @RequestBody Object object即可
Object addStudent(@RequestBody Object object);
还有一种restful的请求参数在url中的方式(由于我的项目问题,并没有使用),也是常见的请求参数传递类型,
例如: /api/selectStudentByName/张三
这时使用 @Param
Object selectStudentByName(@Param("studentName") String studentName);
这样如果你请求的接口是如下:
@RequestMapping("/selectStudentByName/{studentName}")
便可接收到参数
参考:https://www.jianshu.com/p/e99c4083935e
非常感谢这个老兄的文章,特此鸣谢!