openfeign的几种调用方式
一、介绍
先上openfeign
的maven
依赖,这边注册中心用的是nacos
,具体版本看自己的需求
<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
中的注解
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
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);
}
}
}
三、最后
注意跨域,在测试进行下载时,时长遇到跨域问题,请格外注意!
我是半月,祝你幸福!!!