SpringCloud-feign客户端http请求

image.png
  • 注意: feign 默认开启支持ribbon负载均衡

  • 在Eureka测试 Order 服务中 pom中添加依赖,注意feign是从Eureka注册中心中获取请求地址,所以也需要Eureka客户端依赖;
    Order项目地址:https://github.com/liangxifeng833/springcloud/tree/master/eureka/order

         
          
              org.springframework.cloud
              spring-cloud-starter-netflix-eureka-client
          
          
          
              org.springframework.cloud
              spring-cloud-starter-openfeign
          
    
  • 项目启动文件OrderApplicaton.java 新增注解@EnableFeignClients

      package lxf.order;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.loadbalancer.LoadBalanced;
      import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
      import org.springframework.cloud.openfeign.EnableFeignClients;
      import org.springframework.context.annotation.Bean;
      import org.springframework.web.client.RestTemplate;
    
      @SpringBootApplication
      //@EnableEurekaClient 将当前服务注册到Eureka
      @EnableEurekaClient
      //开启feign客户端权限
      @EnableFeignClients
      public class OrderApplication {
    
          public static void main(String[] args) {
          SpringApplication.run(OrderApplication.class, args);
          }
      }
    ``` 
    
    
  • order会员服务中,写fegin接口请求member服务 MemberApiFeign.java

      package lxf.order.api.feign;
      import lxf.order.api.DomainResponse;
      import org.springframework.cloud.openfeign.FeignClient;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import java.util.Map;
      /**
       * 请求远程member服务feign接口
       */
      //app-member就是会员服务注册到Eureka的服务别名
      @FeignClient(name="app-member")
      public interface MemberApiFeign {
    
          //需要请求member服务的getMember方法
          @GetMapping("/getMember")
          public String getFeignMember();
    
          //需要请求member服务的addMember方法
          @PostMapping("/addMember")
          public DomainResponse addFeignMember(@RequestBody Map map);
      }
    
  • MemberFeignController.java调用接口请求member服务

      package lxf.order.api.feign;
    
      import lxf.order.api.DomainResponse;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
    
      import java.util.HashMap;
      import java.util.Map;
    
      /**
       * 使用feign客户端远程请求member服务的get和post请求测试
       */
      @RestController
      public class MemberFeignController {
          @Autowired
          private MemberApiFeign memberApiFeign;
    
          @RequestMapping("/feignMember")
          public DomainResponse feignMember() {
          //测试get请求
          //return memberApiFeign.getFeignMember();
          //测试post请求
          Map map = new HashMap();
          map.put("lan","php");
          map.put("db","mysql");
          DomainResponse res = memberApiFeign.addFeignMember(map);
          System.out.println("response  = " + res);
          return res;
          }
      }
    
  • member服务的api实现代码如下:
    git地址: https://github.com/liangxifeng833/springcloud/blob/master/eureka/member/src/main/java/lxf/member/api/MemberApiController.java

      package lxf.member.api;
    
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RestController;
    
      import java.util.Map;
    
      @RestController
      public class MemberApiController {
          @Value("${server.port}")
          private String serverPort;
          @GetMapping("/getMember")
          public String getMember() {
          return "I am member! server port = "+serverPort;
          }
    
          @PostMapping("/addMember")
          public DomainResponse addMember(@RequestBody Map map) {
          return DomainResponse.ofSuccess(map);
          }
      }
    

########################################################

重构feign客户端

  • 因为order服务中需要定义feign接口,该接口其实就是要访问member中的 getMember接口,我们可以建立接口项目,然后在ordermember中直接实现和调用接口项目中的即可,这样就不想用写重复的代码.多个项目互相依赖请查看:IDEA创建多个模块MavenSpringBoot项目;
  • 先新建parent maven项目,然后在parent项目右键->Module->选择maven项目创建各个子项目.项目创建好的目录结构是:


    image.png

以上目录结构说明:
api-service中包含api-member-serviceapi-order-service这两个service只是接口和实体没有实现;
api-member-service-impl是具体的会员服务实现,该项目依赖api-member-service接口.
api-order-service-impl是具体的订单服务实现,该项目依赖 api-order-servcieapi-member-service两个接口项目,在该项目中使用feign客户端调用远程会员服务接口如下:

import api.member.service.IMemberServcie;
import org.springframework.cloud.openfeign.FeignClient;
/**
 * 使用feign客户端调用远程会员服务接口
 * 该接口继承会员服务api-member-service中的IMemberService接口
 * 就不需要重复写接口了
 */
@FeignClient("app-member")
public interface MemberServiceFeign extends IMemberServcie {
}

OrderServiceImpl实现接口并具体实现远程调用内容如下:

package order.service.impl;

import api.member.entity.User;
import order.service.IOrderService;
import order.service.feign.MemberServiceFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 订单服务controller 实现order-service项目中的接口
 */
@RestController
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private MemberServiceFeign memberServiceFeign;


    @RequestMapping("/orderToMember")
    @Override
    public String orderToMember(String name) {
        User user = memberServiceFeign.getMember(name);
        return user==null ? "找不到用户信息" : user.toString();
    }
}

成功访问结果如下:(注意启动项目顺序:eureka-> api-member-service-impl-> api-order-service-impl)公共接口api-server不需要配置启动文件因为只有接口所以无需启动.

image.png

  • 然后在parent工程的pom中引入如下,就属于spring-boot工程了.就可以在项目中新建包了,否则显示的是新建目录.
    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.1.RELEASE
         
    
  • 特别注意: 如果该项目是war包,则在项目启动文件中必须 extends SpringBootServletInitializer, 且有SpringApplicationBuilder方法,否则war包部署到tomcat后会出现访问404页面.
package order.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
//@EnableEurekaClient 将当前服务注册到Eureka
@EnableEurekaClient
//使用feign客户端调用远程http服务
@EnableFeignClients
public class OrderApplication extends SpringBootServletInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(OrderApplication.class);
    }

}
  • 然后在api-member-servicesrc/main/jave中右键->创建package:api.member.service,然后在这个包内创建IMemberServcie接口

    image.png

  • 注意:即使按着该文章创建好后,在IDEA中启动服务后通过浏览器可以正常方法(IDEA自动帮忙管理依赖),但是通过 mavn clean package打包后发现依赖包找不到:IDEA maven 多模块打包问题总结,这是因为依赖包需要放到私服中,所以就需要搭建内部maven私服:自己手动搭建Nexus私服,

    image.png

具体项目代码地址:https://github.com/liangxifeng833/springcloud/tree/master/parent

你可能感兴趣的:(SpringCloud-feign客户端http请求)