第五章 SpringCloud 使用Feign调用服务

来源:互联网 发布:openssh windows 编辑:程序博客网 时间:2024/06/05 19:42
本章节完整源代码地址:https://github.com/kwang2003/springcloud-study-ch05.git
1.项目概要介绍
在第三章和第四章的学习中,我们已经掌握了通过RestTemplate负载均衡机制来调用注册中心中的服务,除了RestTemplate外,SpringCloud还提供了另一个强大的组件Feign,这让客户端开发人员的编码更加简洁高效。
本章节的代码将以第四章的完整代码为基础进行feign改造实现
https://github.com/kwang2003/springcloud-study-ch04.git
2.服务调用者user-service
feign是工作在服务调用者一方的,因此只要改造user-service工程,将其中通过RestTemplate调用message服务的部分改造成feign即可
a)添加Feign依赖
springcloud-user工程
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

b)项目中启用Feign
在UserApplication主函数类上添加@EnableFeignClients

c)编写FeignClient服务
新增一个接口com.pachiraframework.springcloud.user.service.MessageService
接口使用@FeignClients注解进行标注,注解中接受一个参数,标示出客户端要调用的注册中心中服务的id,用于创建Ribbon负载均衡器
接口中的方法和服务提供者中的定义保持一致,注意,这里我们调用的是SmsController中的send2方法,因为这个方法的接收参数添加了@RequestBody参数

package com.pachiraframework.springcloud.user.service;

import java.util.Map;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.pachiraframework.springcloud.user.controller.UserController.SmsSendResponse;

import lombok.Data;

@FeignClient("message-service")
public interface MessageService {
@RequestMapping(method=RequestMethod.POST,value="/message/sms/send2")
public ResponseEntity<SmsSendResponse> send(SmsSendRequest request);
@Data
public static class SmsSendRequest {
/**
* 短信模版ID
*/
private String templateId;
/**
* 要发送的手机号
*/
private String mobile;
/**
* 模版中携带的参数信息
*/
private Map<String, Object> params;
}
}
d)调用方UserController改造
新增一个regist/sms2方法,用于和先前的基于RestTemplate方法调用区分开

具体代码内容如下
package com.pachiraframework.springcloud.user.controller;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.pachiraframework.springcloud.user.service.MessageService;
import com.pachiraframework.springcloud.user.service.MessageService.SmsSendRequest;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/user/")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private MessageService messageService;
@RequestMapping(value= {"regist/sms"})
public ResponseEntity<SmsSendResponse> sms(String mobile){
Random random = new Random();
int next = random.nextInt(10000000);
String code = ""+(10000000-next);
ResponseEntity<SmsSendResponse> response = doSend(mobile, code);
return response;
}
public ResponseEntity<SmsSendResponse> doSend(String mobile,String code) {
final String sendUrl = "http://message-service/message/sms/send";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("mobile", mobile);
map.add("templateId", "CHECK_CODE");
map.add("params['code']", code);
log.info("发送参数:{}",map);

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<SmsSendResponse> response = restTemplate.postForEntity(sendUrl, request, SmsSendResponse.class);
return response;
}
@RequestMapping(value= {"regist/sms2"})
public ResponseEntity<SmsSendResponse> sms2(String mobile){
Random random = new Random();
int next = random.nextInt(10000000);
String code = ""+(10000000-next);
ResponseEntity<SmsSendResponse> response = doSendFeign(mobile, code);
return response;
}
public ResponseEntity<SmsSendResponse> doSendFeign(String mobile,String code) {
SmsSendRequest request = new SmsSendRequest();
request.setMobile(mobile);
request.setTemplateId("CHECK_CODE");
Map<String, Object> params = new HashMap<>();
params.put("code", code);
request.setParams(params);
return messageService.send(request);
}
@Data
public static class SmsSendResponse {
/**
* 返回消息
*/
private String message;
/**
* 返回状态码
*/
private String code;
}

}
3.测试改造结果
运行UserApplication程序,访问
http://localhost:8082/user/regist/sms2?mobile=1234567895