Spring Cloud 之Feign(三)

八、Feign的通信

Feign是在ribbon的基础上进行的一次封装。需要通过接口层来定义下游的接口和上游的调用。

1.引入依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.编写配置文件

server:
  port: 8764
spring:
  application:
    name: product-feign-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

3.在启动类上打上注解@EnableFeignClients

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class MyProductFeignServiceApplication {

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

}

4.创建接口(通讯接口) 定义了上下游之间通信的标准

  • @FeignClient("USER-SERVICE"):找到服务提供者的名称
  • 在接口中,把需要用到的服务提供者的controller中的接口全部复制到该接口中,并去掉方法体,成为抽象方法。
  • 所有的@RequestParam需要带上name属性
package com.qf.my.product.feign.service.api;

import com.qf.common.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;

@FeignClient("USER-SERVICE")
public interface ProductFeignAPI {


    @RequestMapping("/user/show")
    public String userShow();

    @PostMapping("/addUser")
    public String addUser(@RequestBody User user);

    @GetMapping("/getUserByMap")
    public User getUserByMap(@RequestParam(name = "id") Long id,@RequestParam(name = "name") String name);

    @PostMapping("/addUserWithHeader")
    public String addUserWithHeader(@RequestBody User user,
                                    @CookieValue(name = "login_token") String login_token,
                                    @CookieValue(name="cart_token") String cart_token);


}

5.在业务代码中,使用注入该接口,来进行下游的调用

controller:

package com.qf.my.product.feign.service.controller;

import com.qf.common.entity.User;
import com.qf.my.product.feign.service.api.ProductFeignAPI;
import com.qf.my.product.feign.service.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class ProductController {


    @Autowired
    private IProductService productService;

    @RequestMapping("/user/show")
    public String userShow(){
        return productService.userShow();
    }

    @PostMapping("/addUser")
    public String addUser(@RequestBody User user){
        return productService.addUser(user);
    }

    @GetMapping("/getUserByMap")
    public User getUserByMap(@RequestParam(name = "id") Long id,@RequestParam(name = "name") String name){
        return productService.getUserByMap(id,name);
    }



}

Service:

package com.qf.my.product.feign.service.service.impl;

import com.qf.common.entity.User;
import com.qf.my.product.feign.service.api.ProductFeignAPI;
import com.qf.my.product.feign.service.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ProductServiceImpl implements IProductService {

    @Autowired
    private ProductFeignAPI productFeignAPI;

    @Override
    public String addUser(User user) {
        //执行自己的业务逻辑
        //调用下游服务
        return productFeignAPI.addUser(user);
    }

    @Override
    public User getUserByMap(Long id, String name) {
        return productFeignAPI.getUserByMap(id,name);
    }

    @Override
    public String userShow(){
        return productFeignAPI.userShow();
    }
}

6.feign通过拦截器携带Cookie进行远程调用

1)通过创建拦截器

package com.qf.my.product.feign.service.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.http.HttpEntity;
import org.apache.http.protocol.RequestContent;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.HttpHeaders;

public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        //1.获取当前的request对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        //2.从request对象中获取cookie
        Cookie[] cookies = request.getCookies();
        String cart_token = "";
        String login_token = "";
        if(cookies!=null&&cookies.length!=0)
        for (Cookie cookie : cookies) {
            if("cart_token".equals(cookie.getName())){
                cart_token = cookie.getValue();
                continue;
            }
            if("login_token".equals(cookie.getName())){
                login_token = cookie.getValue();
                continue;
            }
        }
        //3.封装成请求头里的cookie的格式
        String cookie = "cart_token="+cart_token+";"+"login_token="+login_token;
        //4.设置cookie键值对放到请求头
        requestTemplate.header(HttpHeaders.COOKIE,cookie);
    }
}

2)在Feign注解中配置该拦截器

package com.qf.my.product.feign.service.api;

import com.qf.common.entity.User;
import com.qf.my.product.feign.service.interceptor.FeignInterceptor;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;

//配置拦截器,让每次请求都先经过拦截器
@FeignClient(value="USER-SERVICE",configuration = FeignInterceptor.class)
public interface ProductFeignAPI {


    @RequestMapping("/user/show")
    public String userShow();

    @PostMapping("/addUser")
    public String addUser(@RequestBody User user);

    @GetMapping("/getUserByMap")
    public User getUserByMap(@RequestParam(name = "id") Long id,@RequestParam(name = "name") String name);

    @PostMapping("/addUserWithHeader")
    public String addUserWithHeader(@RequestBody User user);


}

posted @ 2021-07-21 21:58  牛奶配苦瓜  阅读(337)  评论(0编辑  收藏  举报