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,看到控制台打印如下信息,说明服务调用成功