SpringCloud服务间的调用有两种方式:RestTemplate和FeignClient。不管是什么方式,他都是通过REST接口调用服务的http接口,参数和结果默认都是通过json序列化和反序列化。因为Spring MVC的RestController定义的接口,返回的数据都是通过Json序列化成JSON数据。
此文章基于上一篇文章的工程
使用RestTemplate进行服务消费
一:编写服务提供者
我们在Mall_WechatService模块编写服务提供者,有三个mapping分别提供get请求,post请求接收json格式的字符串,post请求接收map格式的数据
@Controller
public class ProduceHelloController {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
//get请求
@ResponseBody
@RequestMapping("/helloA")
public String sayHelloA(){
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","king james");
map.put("age",33);
map.put("team","Cleveland Cavaliers");
logger.info(JSON.toJSONString(map));
return JSON.toJSONString(map);
}
//POST请求发送json格式的数据
@ResponseBody
@RequestMapping("/helloB")
public String sayHelloB(@RequestBody(required = false)String requestJson){
try{
JSONObject jsonObject = JSON.parseObject(requestJson);
logger.info("helloB"+requestJson);
return requestJson;
}
catch (Exception e){
logger.info("发生了异常:"+e.getMessage());
return "error";
}
}
//POST请求用Map接收
@ResponseBody
@RequestMapping("/helloC")
public String sayHelloC(@RequestBody Map<String, Object> params){
try{
logger.info("helloC"+JSON.toJSONString(params));
return JSON.toJSONString(params);
}
catch (Exception e){
logger.info("发生了异常:"+e.getMessage());
return "error";
}
}
}
二:编写服务消费者
我们在Mall_ManagerService模块编写服务消费者,分别对应上面的三个请求
首先编写RestTemplate的配置
@Configuration
public class ResTemplateConfig {
@Bean
//加上这个标签会有负载均衡的效果
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
编写消费的controller
@Controller
public class HelloController {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Autowired
private RestTemplate restTemplate;
String host = "http://mall-wechatservice";//Mall_WechatService模块的spring.application.name
@ResponseBody
@RequestMapping("/sayHelloA")
public String getInfoFromWechatA(){
String url = host+"/helloA";
String text = restTemplate.getForObject(url,String.class);
logger.info("text:"+ text);
return text;
}
@ResponseBody
@RequestMapping("/sayHelloB")
public String getInfoFromWechatB(){
String url = host+"/helloB";
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","king james");
map.put("age",33);
map.put("team","Cleveland Cavaliers");
String text = restTemplate.postForObject(url,JSON.toJSONString(map),String.class);
logger.info("text:"+ text);
return text;
}
@ResponseBody
@RequestMapping("/sayHelloC")
public String getInfoFromWechatC(){
String url = host+"/helloC";
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","king james");
map.put("age",33);
map.put("team","Cleveland Cavaliers");
String text = restTemplate.postForObject(url,map,String.class);
logger.info("text:"+ text);
return text;
}
}
我们请求服务消费者的三个URL,然后可以看到Mall_WechatService模块能够正确提供信息并且返回,下面是打印信息
使用Feign进行服务消费
编写服务消费者
首先导入Feign的pom依赖文件,这里一定要注意的是,在SpringCloud最新版本,基于SpringBoot2.0+版本当中,feign的依赖是:
<!--项目使用Feign作为Rest客户端进行远程调用,Spring Cloud版本升级后,Feign依赖变更为:-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在旧的版本当中,则引入如下依赖:
<!--老版本的springcloud当中的feign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
在主类上面加上@EnableFeignClients注解开启Feign的功能
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
public class MallManagerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MallManagerServiceApplication.class, args);
}
}
编写feign接口,调用服务
//括号里面就是你要调用服务的spring.application.name的值
//在这里,我需要去调用mall_wechatservice当中的hello服务
@FeignClient("mall-wechatservice")
public interface HelloServiceRestful {
/**
* 请求mall_wechatservice模块的helloA
* @return
*/
@RequestMapping("/helloA")
public String getInfoFromWechatA();
/**
* 请求mall_wechatservice模块的helloB
* @return
*/
@RequestMapping("/helloB")
public String getInfoFromWechatB(@RequestBody String json);
/**
* 请求mall_wechatservice模块的helloC
* @return
*/
@RequestMapping("/helloC")
public String getInfoFromWechatC(@RequestBody Map<String, Object> params);
}
定义controller,调用服务
@Controller
public class FeignHelloController {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Autowired
private HelloServiceRestful helloServiceRestful;
@ResponseBody
@RequestMapping("sayFeignHello")
public String getInfoFromWechat(){
String text = helloServiceRestful.getInfoFromWechatA();
logger.info("A"+text);
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","king james");
map.put("age",33);
map.put("team","Cleveland Cavaliers");
text = helloServiceRestful.getInfoFromWechatB(JSON.toJSONString(map));
logger.info("B"+text);
text = helloServiceRestful.getInfoFromWechatC(map);
logger.info("C"+text);
return text;
}
}
我们输入http://localhost:8011/sayFeignHello,看到控制台打印如下信息,说明服务调用成功