第六篇:【Spring Cloud】RestTemplate FeignClient使用

  • RestTemplate使用方式

1.创建user项目 pom文件见如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.cohesion</groupId>
    <artifactId>spring-cloud-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>spring-cloud-user</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <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-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>  
           <groupId>com.alibaba</groupId>  
           <artifactId>fastjson</artifactId>  
           <version>1.2.15</version>  
        </dependency>
        <dependency>
            <groupId>com.github.miemiedev</groupId>
            <artifactId>mybatis-paginator</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.3</version>
        </dependency>
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>0.9.4</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

 

 

2.标记自己是消费者

package com.cohesion;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient//标记自己是消费者
public class SpringCloudUserApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudUserApplication.class, args);
    }
}

3.修改配置文件 application.yml文件

server:
  port: 8083

spring:
  application:
    name: service-user

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/

service:
  url:
    order: service-order#订单服务

 

4.创建UserController

package com.cohesion.user.rest;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cohesion.entity.ResponseModel;
import com.cohesion.util.ApiUtils;
import com.cohesion.util.RemoteLoad;
@RestController
public class UserController extends RemoteLoad{
    
    @Value("${service.url.order}")
    private String serviceOrderUrl;    
 
    @RequestMapping(value="/testRestTemplate")
    public ResponseModel testRestTemplate(HttpServletRequest request){
         HashMap<String, Object> par = new HashMap<String, Object>();
        //request值放到HashMap中
        ApiUtils.setRequestPar(request,par);
        //postRestObject参数说明
        //【0】服务名称 serviceOrderUrl
        //【1】接口地址 /order/getUserOrderInfo
        //【2】返回类型 ResponseModel.class
        //【3】参数类型 par
          ResponseModel res = postRestObject(serviceOrderUrl, "/order/getUserOrderInfo", ResponseModel.class, par);
        return res;
    }
}

5.创建依赖的工具类

ResponseModel

package com.cohesion.entity;

import java.io.Serializable;

public class ResponseModel implements Serializable{
     private static final long serialVersionUID = 5285476448351872035L;
      private int status;
      private String msg;
      private Object data;
      private Object perm;
      
      public ResponseModel() {}
      
      public ResponseModel(int status, String msg, Object data)
      {
        this.status = status;
        this.msg = msg;
        this.data = data;
      }
      
      public int getStatus()
      {
        return this.status;
      }
      
      public void setStatus(int status)
      {
        this.status = status;
      }
      
      public String getMsg()
      {
        return this.msg;
      }
      
      public void setMsg(String msg)
      {
        this.msg = msg;
      }
      
      public Object getData()
      {
        return this.data;
      }
      
      public void setData(Object data)
      {
        this.data = data;
      }
      
      public Object getPerm()
      {
        return this.perm;
      }
      
      public void setPerm(Object perm)
      {
        this.perm = perm;
      }
}

 

 UserConfig

package com.cohesion.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class UserConfig {
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

ApiUtils

package com.cohesion.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

public class ApiUtils {
    //把request中的数据放到map中
    public static void setRequestPar(HttpServletRequest request, HashMap<String, Object> par) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (String key : parameterMap.keySet()) {
            if (parameterMap.get(key) != null && parameterMap.get(key).length == 1) {
                par.put(key, parameterMap.get(key)[0]);
            }
        }
    }
}

RemoteLoad

package com.cohesion.util;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import com.google.common.base.Joiner;
@Component
public class RemoteLoad {
 
    @Autowired
    private RestTemplate rest;
 
    public <T> T postRestObject(String serviceName, String url, Class<T> clazz, Map<String, Object> pars) {
        return postRestObjectRetry(serviceName, url, clazz, pars, 0);
    }

    private <T> T postRestObjectRetry(String serviceName, String url, Class<T> clazz, Map<String, Object> pars,
            Integer retryTime) {
        try {
            T data = rest.postForObject(Joiner.on("").join("http://",serviceName, url), convertPar(pars), clazz);
            return data;
        } catch (Exception e) {
            // TODO: handle exception
            if (retryTime < 3) {
                return postRestObjectRetry(serviceName, url, clazz, pars, retryTime + 1);
            }
            e.printStackTrace();
            return null;
        }
    }
    //把map放到MultiValueMap中 用来传值
    private MultiValueMap<String, Object> convertPar(Map<String, Object> par) {
        MultiValueMap<String, Object> result = new LinkedMultiValueMap<String, Object>();
        if (par == null) {
            return result;
        }
        for(String key:par.keySet()) {
            result.add(key, par.get(key));
        }
        return result;
    }
    
}

6.验证

6.1直接方式user服务

现在服务和服务之间调用和传参已经ok了,我们来看下结果。

这个是直接调用8083 【user】服务的,可以看到我们传什么值过去,order服务就返回什么值回来,表示传真和服务之间是没问题的。

 

6.2 通过zuul访问【user】服务

zuul的配置文件我这边多了一个user服务,只要是user开头的请求,都会转到user服务

server:
  port: 9000

spring:
  application:
    name: service-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/
   
zuul:
  routes:
    order:
      path: /order/**
      service-id: SERVICE-ORDER
    user:
      path: /user/**
      service-id: SERVICE-USER

 

 

  • FeignClient使用方式

 7.FeignClient

【pom】文件新增一个属性

<dependency>
            <groupId>org.springframework.cloud</groupId>
</dependency>

8.新增接口文件

FeignClientTest

package com.cohesion.remote;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.cohesion.entity.ResponseModel;

@FeignClient(name = "SERVICE-ORDER")
public interface FeignClientTest {
    
    @GetMapping("/testFeignClient")//这里是order项目中的接口地址 和接口参数
    ResponseModel productBrandPage(
    @RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex);
}

9.修改userController类 增加对接口的实现

package com.cohesion.user.rest;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cohesion.entity.ResponseModel;
import com.cohesion.remote.FeignClientTest;
import com.cohesion.util.ApiUtils;
import com.cohesion.util.RemoteLoad;
@RestController
public class UserController extends RemoteLoad{
    
    @Value("${service.url.order}")
    private  String serviceOrderUrl;    
    
    @Autowired
    private FeignClientTest feignClientTest;
    
    @RequestMapping(value="/testRestTemplate")
    public ResponseModel testRestTemplate(HttpServletRequest request){
         HashMap<String, Object> par = new HashMap<String, Object>();
        //request值放到HashMap中
        ApiUtils.setRequestPar(request,par);
        //postRestObject参数说明
        //【0】服务名称 serviceOrderUrl
        //【1】接口地址 /order/getUserOrderInfo
        //【2】返回类型 ResponseModel.class
        //【3】参数类型 par
          ResponseModel res = postRestObject(serviceOrderUrl, "/order/getUserOrderInfo", ResponseModel.class, par);
        return res;
    }
    
    @RequestMapping(value="/testFeignClient")
    public ResponseModel testFeignClient(HttpServletRequest request){
        Integer pageIndex = Integer.parseInt(request.getParameter("pageIndex"));
        ResponseModel res = feignClientTest.productBrandPage(pageIndex);
        return res;
    }
}

10.修改【order】服务代码

package com.cohesion.rest;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.cohesion.entity.ResponseModel;
import com.cohesion.utils.SystemUtils;
 
@RestController
public class OrderController {
    @Value("${server.port}")
    private String port;
    
    @Value("${spring.application.name}")
    private String serviceName;
    
    @RequestMapping(value="/order/helloWord")
    public String helloWord() {
         String returnStr = "您访问的是:【"+serviceName+"】服务,【端口号】"+port;
        return returnStr;
    }
    
    @RequestMapping(value="/order/getUserOrderInfo")
    public ResponseModel getUserOrderInfo(HttpServletRequest request) {
        ResponseModel responseModel = new ResponseModel(200,"成功",null);
        HashMap<String, Object> par = new HashMap<String, Object>();
        //把request中的参数放到HashMap中
        SystemUtils.setRequestParamater(par, request);
        System.out.println(par.get("id")+request.getParameter("id"));
        //传怎什么值过来 就返回怎么值 检测服务之间通信是否畅通
        responseModel.setData(par);
        return responseModel;
    }
    
    @RequestMapping(value = "/testFeignClient")
    public ResponseModel testFeignClient(HttpServletRequest request) {
        ResponseModel responseModel = new ResponseModel(200,"成功",null);
        HashMap<String, Object> par = new HashMap<String, Object>();
        //把request中的参数放到HashMap中
        SystemUtils.setRequestParamater(par, request);
         //传怎什么值过来 就返回怎么值 检测服务之间通信是否畅通
        responseModel.setData(par);
        return responseModel;
    }
    

}

11.验证

11.1直接访问user项目 测试Feign

11.2直接访问ZUUL项目 测试Feign

 

 

可以看到 数据从user传到order 又把参数带回来了,表示通信正常。

posted @ 2018-07-30 17:13  IT-Jack  阅读(5811)  评论(0编辑  收藏  举报