openfeign的几种调用方式

2023-03-03 15:03:57 浏览数 (2)

openfeign的几种调用方式

一、介绍

先上openfeignmaven依赖,这边注册中心用的是nacos,具体版本看自己的需求

代码语言:javascript复制
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

二、示例代码

1)客户端

代码语言:javascript复制
package com.banmoon.client1.controller;

import com.banmoon.client1.service.TestService;
import com.banmoon.common.ResultData;
import com.banmoon.common.dto.UploadDTO;
import com.banmoon.common.dto.UserDTO;
import com.banmoon.common.entities.UserEntity;
import com.banmoon.common.utils.MyFileUtil;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired(required = false)
    private TestService testService;

    @GetMapping("/simpleGet")
    public ResultData<UserEntity> simpleGet(@RequestParam Integer id) {
        return testService.simpleGet(id);
    }

    @GetMapping("/pathGet/{id}")
    public ResultData<UserEntity> pathGet(@PathVariable Integer id) {
        return testService.pathGet(id);
    }

    @PostMapping("/mapPost")
    public ResultData<List<UserEntity>> mapPost(@RequestBody Map<String, Object> params) {
        return testService.mapPost(params);
    }

    @PostMapping("/dtoPost")
    public ResultData<List<UserEntity>> dtoPost(@RequestBody UserDTO userDTO) {
        return testService.dtoPost(userDTO);
    }

    @DeleteMapping("/delete")
    public ResultData delete(@RequestBody Long[] ids) {
        return testService.delete(ids);
    }

    @PutMapping("/put")
    public ResultData put(@RequestBody UserDTO userDTO) {
        return testService.put(userDTO);
    }

    /**
     * 导出,下载
     * @param userDTO
     * @param response
     */
    @PostMapping("/export")
    public void export(@RequestBody UserDTO userDTO, HttpServletResponse response) {
        try {
            Response feignResponse = testService.export(userDTO);
            InputStream inputStream = feignResponse.body().asInputStream();
            MyFileUtil.downloadFile(response, inputStream, "测试.jpg");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传
     * @param dto
     * @return
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResultData upload(UploadDTO dto) {
        return testService.upload(dto);
    }

}

openfeign的使用,可以使用springMVC中的注解

代码语言:javascript复制
package com.banmoon.client1.service;

import com.banmoon.common.ResultData;
import com.banmoon.common.constant.ServerNameConstant;
import com.banmoon.common.dto.UploadDTO;
import com.banmoon.common.dto.UserDTO;
import com.banmoon.common.entities.UserEntity;
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@FeignClient(name = ServerNameConstant.SERVER_ONE)
public interface TestService {

    @RequestMapping(value = "/test/simpleGet", method = RequestMethod.GET)
    ResultData<UserEntity> simpleGet(@RequestParam("id") Integer id);

    @RequestMapping(value = "/test/pathGet/{id}", method = RequestMethod.GET)
    ResultData<UserEntity> pathGet(@PathVariable("id") Integer id);

    @RequestMapping(value = "/test/mapPost", method = RequestMethod.POST)
    ResultData<List<UserEntity>> mapPost(@RequestBody Map<String, Object> params);

    @RequestMapping(value = "/test/dtoPost", method = RequestMethod.POST)
    ResultData<List<UserEntity>> dtoPost(@RequestBody UserDTO userDTO);

    @RequestMapping(value = "/test/delete", method = RequestMethod.DELETE)
    ResultData delete(@RequestBody Long[] ids);

    @RequestMapping(value = "/test/put", method = RequestMethod.PUT)
    ResultData put(@RequestBody UserDTO userDTO);

    @RequestMapping(value = "/test/export", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    Response export(@RequestBody UserDTO userDTO);

    @PostMapping(value = "/test/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    ResultData upload(UploadDTO dto);
}

2)服务端

代码语言:javascript复制
package com.banmoon.server.controller;

import cn.hutool.core.io.IoUtil;
import com.banmoon.common.ResultData;
import com.banmoon.common.dto.UploadDTO;
import com.banmoon.common.dto.UserDTO;
import com.banmoon.common.entities.UserEntity;
import com.banmoon.common.utils.MyFileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@CrossOrigin(exposedHeaders = {"Content-Disposition", "Access-Control-Allow-Origin"})
@RestController
@RequestMapping("/test")
public class TestController {

    public static final List<UserEntity> userList = new ArrayList<UserEntity>() {{
        add(new UserEntity(1, "banmoon", 18, "男"));
        add(new UserEntity(2, "hh", 22, "男"));
        add(new UserEntity(3, "xiao", 18, "女"));
        add(new UserEntity(4, "kun", 22, "女"));
    }};

    @GetMapping("/simpleGet")
    public ResultData<UserEntity> simpleGet(@RequestParam Integer id) {
        UserEntity userEntity = userList.stream().filter(user -> user.getId().equals(id)).findFirst().orElse(null);
        return ResultData.success(userEntity);
    }

    @GetMapping("/pathGet/{id}")
    public ResultData<UserEntity> pathGet(@PathVariable Integer id) {
        UserEntity userEntity = userList.stream().filter(user -> user.getId().equals(id)).findFirst().orElse(null);
        return ResultData.success(userEntity);
    }

    @PostMapping("/mapPost")
    public ResultData<List<UserEntity>> mapPost(@RequestBody Map<String, Object> params) {
        log.info("入参:{}", params);
        return ResultData.success(userList);
    }

    @PostMapping("/dtoPost")
    public ResultData<List<UserEntity>> dtoPost(@RequestBody UserDTO userDTO) {
        log.info("入参:{}", userDTO);
        return ResultData.success(userList);
    }

    @DeleteMapping("/delete")
    public ResultData delete(@RequestBody Long[] ids) {
        log.info("入参:{}", ids);
        return ResultData.success();
    }

    @PutMapping("/put")
    public ResultData put(@RequestBody UserDTO userDTO) {
        log.info("入参:{}", userDTO);
        return ResultData.success();
    }

    @PostMapping(value = "/export", produces = MediaType.APPLICATION_JSON_VALUE)
    public void export(@RequestBody UserDTO userDTO, HttpServletResponse response) throws Exception {
        log.info("入参:{}", userDTO);
        String str = "E:\downFile\fireFox\Cyberpunk-edgerunners-lucy-edgerunners-anime-girls-Cyberpunk-2077-cyberpunk-Netflix-TV-Series-2179331-wallhere.com.jpg";
        File file = new File(str);
        MyFileUtil.downloadFile(response, file, "测试.jpg");
    }

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResultData upload(UploadDTO dto) {
        try {
            MultipartFile file = dto.getFile();
            String fileName = dto.getFileName();
            String path = System.getProperty("java.io.tmpdir")   fileName;
            File targetFile = new File(path);
            FileOutputStream outputStream = new FileOutputStream(targetFile);
            InputStream inputStream = file.getInputStream();
            IoUtil.copy(inputStream, outputStream);
            IoUtil.close(outputStream);
            IoUtil.close(inputStream);
            return ResultData.success();
        } catch (IOException e) {
            e.printStackTrace();
            return ResultData.fail("上传失败");
        }
    }

}

其他的都好说,主要是这个下载,有遇到流在openfeign中流转需求时,

需要将服务端的返回值设置为void

openfeign的调用服务,他的返回值需要设置为feign.Response

然后再从其中取到输出流转输入流,再从客户端的selvet输出流进行输出

3)其他代码

如果微服务众多的话,可以将其进行统一常量管理

代码语言:javascript复制
package com.banmoon.common.constant;

public class ServerNameConstant {

    public static final String SERVER_ONE = "server1";

}

两个传输使用的DTO

代码语言:javascript复制
package com.banmoon.common.dto;

import lombok.Data;
import org.springframework.web.multipart.MultipartFile;

@Data
public class UploadDTO {

    private MultipartFile file;

    private String fileName;

}
代码语言:javascript复制
package com.banmoon.common.dto;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class UserDTO {

    private Integer id;

    private String username;

    private Integer age;

    private String sex;

}

一个统一的返回类

代码语言:javascript复制
package com.banmoon.common;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultData<T> {

    private Integer errCode;

    private String errMsg;

    private T data;

    public static ResultData success(){
        return new ResultData(0, "成功", null);
    }

    public static ResultData fail(String errMsg){
        return new ResultData(-1, errMsg, null);
    }

    public static <T> ResultData success(T t) {
        return new ResultData(0, "成功", t);
    }
}

一个实体类

代码语言:javascript复制
package com.banmoon.common.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserEntity {

    private Integer id;

    private String username;

    private Integer age;

    private String sex;

}

重点的文件工具类

代码语言:javascript复制
package com.banmoon.common.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@Slf4j
public class MyFileUtil {

    public static void downloadFile(HttpServletResponse response, ExcelWriter writer, String filename){
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition","attachment;filename="   URLEncoder.encode(filename, "UTF-8"));

            writer.flush(out, true);
        } catch (IOException e) {
            log.error("io异常", e);
        } finally {
            writer.close();
            IoUtil.close(out);
        }
    }

    public static void downloadFile(HttpServletResponse response, File file, String filename){
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition","attachment;filename="   URLEncoder.encode(filename, "UTF-8"));
            response.setHeader("Content-Length", String.valueOf(FileUtil.size(file)));

            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            IoUtil.copy(fis, toClient);
            out.flush();
        } catch (Exception e) {
            log.error("io异常", e);
        } finally {
            IoUtil.close(out);
        }
    }

    public static void downloadFile(HttpServletResponse response, InputStream inputStream, String filename) {
        try {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition","attachment;filename="   URLEncoder.encode(filename, "UTF-8"));
            ServletOutputStream outputStream = response.getOutputStream();
            IoUtil.copy(inputStream, outputStream);
        } catch (Exception e) {
            log.error("io异常", e);
        }
    }

}

三、最后

注意跨域,在测试进行下载时,时长遇到跨域问题,请格外注意!

我是半月,祝你幸福!!!

0 人点赞