openfeign的几种调用方式
一、介绍
先上openfeign
的maven
依赖,这边注册中心用的是nacos
,具体版本看自己的需求
1 2 3 4 5 6 7 8 9
| <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)客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| 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); }
@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(); } }
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResultData upload(UploadDTO dto) { return testService.upload(dto); }
}
|
openfeign
的使用,可以使用springMVC
中的注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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)服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| 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)其他代码
如果微服务众多的话,可以将其进行统一常量管理
1 2 3 4 5 6 7
| package com.banmoon.common.constant;
public class ServerNameConstant {
public static final String SERVER_ONE = "server1";
}
|
两个传输使用的DTO
1 2 3 4 5 6 7 8 9 10 11 12 13
| package com.banmoon.common.dto;
import lombok.Data; import org.springframework.web.multipart.MultipartFile;
@Data public class UploadDTO {
private MultipartFile file;
private String fileName;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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;
}
|
一个统一的返回类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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); } }
|
一个实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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;
}
|
重点的文件工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| 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); } }
}
|
三、最后
注意跨域,在测试进行下载时,时长遇到跨域问题,请格外注意!
我是半月,祝你幸福!!!