IDEA项目搭建七——使用Feign简化消费者端操作(controller不用rest风格)

 

https://www.cnblogs.com/taiyonghai/p/9306244.html

 

 

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 {

 

    //自动注入请求对象,查看header信息

    @Autowired

    HttpServletRequest request;

 

    @Autowired

    HotelService service;

 

    @ResponseBody

    @RequestMapping("/test")

    public void test() {

        //do something...

    }

 

    @ResponseBody

    @RequestMapping("/get")

    public BaseInfoModel get(@RequestParam(defaultValue = "0") int id) {

        String tyh = request.getHeader("taiyonghai");//获取Header头信息

        System.out.println("参数为:" + id);

        return service.get(id);

    }

    //设置参数为@RequestBody可以自动序列化为对象

    @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 bootspring cloudfeign的引用 

 

    <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>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

  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文件夹,新建HotelServiceInterface用来执行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);

 

    //自定义类型参数以及泛型返回值

    @RequestMapping("/list")

    ResponseModel<List<BaseInfoModel>> list(@RequestBody SearchModel search);

}

 

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

 

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 {

 

    //自动注入Feign接口对象

    @Autowired

    HotelService service;

 

    @RequestMapping("/get")

    public String get(Model model) {

        //像调用方法一样调用即可实现服务生产者端的调用

        model.addAttribute("model",service.get(1));

        return "/hotel/get";

    }

 

    //直接返回json不写页面了

    @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文件夹下建立templateshotel文件夹,新建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了

 

posted @   烁妈妈  阅读(454)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示