zoukankan      html  css  js  c++  java
  • IDEA项目搭建七——使用Feign简化消费者端操作

    一、简介

    我们可以看到上一篇文章的消费者这边调用Service时比较麻烦,所以我们可以使用Feign来简化这部分操作,它底层也是使用Ribbon实现的只是Ribbon支持HTTP和TCP两种通信协议,而Feign只支持HTTP一种,同样支持负载均衡,所以能满足90%以上的需求了。

    二、搭建生产者模块

    其实这部分是通用的,对于消费者这边使用什么Client并没有影响,Eureka还是使用之前搭建好的,生产者模块也用搭建好的,我们新建一个controller用于承接service,这边就算完成了

    复制代码
    import javademo.tyh.model.hotel.BaseInfoModel;
    import javademo.tyh.model.hotel.ResponseModel;
    import javademo.tyh.model.hotel.SearchModel;
    import javademo.tyh.service.hotel.service.HotelService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    

    import javax.servlet.http.HttpServletRequest;
    import java.util.List;

    @Controller
    @RequestMapping("/api/hotel")
    public class HotelController {

    </span><span style="color: #008000;">//</span><span style="color: #008000;">自动注入请求对象,查看header信息</span>
    

    @Autowired
    HttpServletRequest request;

    @Autowired
    HotelService service;
    
    @ResponseBody
    @RequestMapping(</span>"/test"<span style="color: #000000;">)
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> test() {
        </span><span style="color: #008000;">//</span><span style="color: #008000;">do something...</span>
    

    }

    @ResponseBody
    @RequestMapping(</span>"/get"<span style="color: #000000;">)
    </span><span style="color: #0000ff;">public</span> BaseInfoModel get(@RequestParam(defaultValue = "0") <span style="color: #0000ff;">int</span><span style="color: #000000;"> id) {
        String tyh </span>= request.getHeader("taiyonghai"<span style="color: #000000;">);<span style="color: #008000;">//获取Header头信息</span>
        System.out.println(</span>"参数为:" +<span style="color: #000000;"> id);
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> service.get(id);
    }
    </span><span style="color: #008000;">//</span><span style="color: #008000;">设置参数为@RequestBody可以自动序列化为对象</span>
    

    @ResponseBody
    @RequestMapping(
    "/list")
    public ResponseModel<List<BaseInfoModel>> list(@RequestBody SearchModel search) {
    System.out.println(
    "参数为:" + search.getName());
    List
    <BaseInfoModel> list = service.list();
    ResponseModel
    <List<BaseInfoModel>> respModel = new ResponseModel<>();
    respModel.setCode(
    "000000");
    respModel.setMsg(
    "操作成功");
    respModel.setData(list);
    return respModel;
    }
    }

    复制代码

    添加通用Model实体,同样不生成get/set方法,自己生成吧

    复制代码
    import com.baomidou.mybatisplus.annotations.TableName;
    import java.time.LocalDateTime;
    

    @TableName("base_info")
    public class BaseInfoModel {
    private int id;
    private String nickname;
    private LocalDateTime updateTime;
    }

    复制代码
    public class SearchModel {
        private int id;
        private String name;
    }
    public class ResponseModel<T> {
        private String code;
        private String msg;
        private T data;
    }

      

     三、搭建消费者模块——Feign

    还是创建一个Maven模块,看一下我的项目结构

      

    1、修改pom.xml文件,增加对spring boot、spring cloud、feign的引用 

    复制代码
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>2.0.3.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <dependencies>
            <!-- import spring boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- import openfeign -->
            <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-openfeign</artifactId>
            </dependency>
        </dependencies>
    
    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">build</span><span style="color: #0000ff;">&gt;</span>
        <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">plugins</span><span style="color: #0000ff;">&gt;</span>
            <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">plugin</span><span style="color: #0000ff;">&gt;</span>
                <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">groupId</span><span style="color: #0000ff;">&gt;</span>org.springframework.boot<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">groupId</span><span style="color: #0000ff;">&gt;</span>
                <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">artifactId</span><span style="color: #0000ff;">&gt;</span>spring-boot-maven-plugin<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">artifactId</span><span style="color: #0000ff;">&gt;</span>
            <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">plugin</span><span style="color: #0000ff;">&gt;</span>
        <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">plugins</span><span style="color: #0000ff;">&gt;</span>
    <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">build</span><span style="color: #0000ff;">&gt;</span></pre>
    
    复制代码

      2、新建resources文件夹,新建application.yml配置文件,并修改内容如下

    复制代码
    #设置自己的程序名称
    spring:
      application:
        name: javademo-tyh-web-hotel
      #thymeleaf 配置
      thymeleaf:
        encoding: UTF-8
        prefix: classpath:/templates
        cache: false
    #服务注册中心地址(刚刚搭建的Eureka Server的地址)
    eureka:
      client:
        #是否向服务中心注册自己
        register-with-eureka: false
        #设置eureka服务中心的地址
        service-url:
          defaultZone: http://localhost:11000/eureka
    #设置自己启动的端口
    server:
      port: 13000
    复制代码

     3、修改main()方法的类,增加Feign的注解

    复制代码
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    

    //引入Feign注解
    @EnableFeignClients
    @SpringBootApplication
    public class AppWebHotel {
    public static void main(String[] args) {
    SpringApplication.run(AppWebHotel.
    class, args);
    }
    }

    复制代码

     4、新建service文件夹,新建HotelService的Interface用来执行Feign向后端服务生产者的调用,指明服务生产者名称,接口方法指明具体的服务路由,这种方式比Ribbon简单很多,而且更直观更像调用后台方法

    复制代码
    import javademo.tyh.model.hotel.BaseInfoModel;
    import javademo.tyh.model.hotel.ResponseModel;
    import javademo.tyh.model.hotel.SearchModel;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.stereotype.Service;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import java.util.List;
    

    @Service
    @FeignClient("javademo-tyh-service-hotel")//指明服务生产者名称
    @RequestMapping("/api/hotel")//此位置的mapping与controller上的mapping是共享全局唯一的,如果这里的名字和controller的路由相同会报错ambiguous mapping
    public interface HotelService {
    // //无参数无返回值
    // @RequestMapping("/test")
    // void test();
    //基础类型参数
    @RequestMapping("/get")
    BaseInfoModel get(@RequestParam(
    "id") int id);

    </span><span style="color: #008000;">//</span><span style="color: #008000;">自定义类型参数以及泛型返回值</span>
    @RequestMapping("/list"<span style="color: #000000;">)
    ResponseModel</span>&lt;List&lt;BaseInfoModel&gt;&gt;<span style="color: #000000;"> list(@RequestBody SearchModel search);
    

    }

    复制代码

      5、新建controller文件夹,新建HotelController的class用来接收页面调用

    复制代码
    import javademo.tyh.model.hotel.BaseInfoModel;
    import javademo.tyh.model.hotel.ResponseModel;
    import javademo.tyh.model.hotel.SearchModel;
    import javademo.tyh.web.hotel.service.HotelService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import java.util.List;
    

    @Controller
    @RequestMapping("/hotel")
    public class HotelController {

    </span><span style="color: #008000;">//</span><span style="color: #008000;">自动注入Feign接口对象</span>
    

    @Autowired
    HotelService service;

    @RequestMapping(</span>"/get"<span style="color: #000000;">)
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String get(Model model) {
        </span><span style="color: #008000;">//</span><span style="color: #008000;">像调用方法一样调用即可实现服务生产者端的调用</span>
        model.addAttribute("model",service.get(1<span style="color: #000000;">));
        </span><span style="color: #0000ff;">return</span> "/hotel/get"<span style="color: #000000;">;
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">直接返回json不写页面了</span>
    

    @ResponseBody
    @RequestMapping(
    "/list")
    public List<BaseInfoModel> list() {
    SearchModel search
    = new SearchModel();
    search.setId(
    1);
    search.setName(
    "taiyonghai");
    ResponseModel
    <List<BaseInfoModel>> result = service.list(search);
    return result.getData();
    }
    }

    复制代码

     6、在resources文件夹下建立templates及hotel文件夹,新建get.html页面,用来渲染数据

    复制代码
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>this is /hotel/get</h1>
    

    <label th:text="${model.Id}">id</label>
    <label th:text="${model.Nickname}">Nickname</label>
    <label th:text="${model.UpdateTime}">UpdateTime</label>

    </body>
    </html>

    复制代码

     OK,现在启动Eureka注册中心、启动服务生产者、启动服务消费者访问http://localhost:13000/hotel/get就可以看到从service取到的结果了

    本应该在这里就完成了,但有时候我们需要在Header头信息中增加些公共内容,在Feign中就可以使用如下方式实现

    在消费者这边的service文件夹下新建FeignInterceptor实现RequestInterceptor接口

    复制代码
    import feign.RequestInterceptor;
    import feign.RequestTemplate;
    import org.springframework.stereotype.Component;
    

    //使用拦截器添加Header头信息
    @Component
    public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
    System.out.println(
    "调用了FeignInterceptor");
    requestTemplate.header(
    "taiyonghai", "1111111111111");
    }
    }

    复制代码

     Feign的简单使用就OK了

    原文地址:https://www.cnblogs.com/taiyonghai/p/9306244.html

  • 相关阅读:
    [Python] Python 学习
    [其它] 学习杂记
    [.NET] 《Effective C#》快速笔记(三)- 使用 C# 表达设计
    [.NET] 《Effective C#》快速笔记(二)- .NET 资源托管
    [python] 小游戏
    [.NET] 《Effective C#》快速笔记(一)- C# 语言习惯
    [angularjs] AngularJs 知识回顾
    [C#] 使用 StackExchange.Redis 封装属于自己的 RedisHelper
    [.NET] 一步步打造一个简单的 MVC 电商网站
    [.NET] 一步步打造一个简单的 MVC 电商网站
  • 原文地址:https://www.cnblogs.com/jpfss/p/12107152.html
Copyright © 2011-2022 走看看