zoukankan      html  css  js  c++  java
  • 第六篇:【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 又把参数带回来了,表示通信正常。

  • 相关阅读:
    CAP 与数据一致性
    C++的构造函数为何不能为虚函数
    构造函数和析构函数中可以调用调用虚函数吗
    HTTP状态码
    C++ 单例模式实现
    【转】十大经典排序算法
    C++ short/int/long/long long 等数据类型大小
    块/文件/对象三种存储的优缺点
    罗振宇《时间的朋友》2019-2020
    Google Hacking
  • 原文地址:https://www.cnblogs.com/sz-jack/p/9391605.html
Copyright © 2011-2022 走看看