Feign 인터페이스 방법 반환 값 설정 방식
마이크로 서비스의 광범 위 한 응용 에 따라 점점 더 많은 기업 들 이 마이크로 서 비 스 를 이용 하여 프로젝트 개발 을 할 것 이다.각 서비스 간 에 feign 을 통 해 통신 을 해 야 하기 때문에 feign 호출 인터페이스 에서 방법 은 다른 서비스 인터페이스의 서로 다른 유형의 반환 값 을 받 아들 일 것 이다.
2.반환 값 설정
1.호출 된 서비스 인터페이스 에 따라 같은 반환 유형 을 설정 합 니 다.
소개:마이크로 서비스 A 인터페이스 getUser 는 List
특징:반환 유형 이 일일이 대응 하여 호출 할 때 전환 하지 않 고 직접 가 져 오 면 사용 할 수 있 습 니 다.
단점:확장 성 이 좋 지 않 고 유지 보수 성 이 좋 지 않 습 니 다.
설명:현재 springboot 개발 에서 인 터 페 이 스 는 일반적으로 json 형식 데이터(즉,@restController 를 사용 하거나@Response Body 주석 수식 을 사용)를 되 돌려 줍 니 다.대상 이나 대상 이 집합 하 더 라 도 마찬가지 이거 나 자신 이 봉 인 된 반환 대상 입 니 다.만약 에 서로 다른 반환 대상 이 많다 면 이러한 반환 대상 이 A 서비스 에서 해당 하 는 B 서비스의 feign 인터페이스 에서 도 수정 을 해 야 한다.상당히 번 거 롭 고 자바 가 인터페이스 프로 그래 밍 사상 에 부합 되 지 않 는 다.
2、모두 String 으로 설정
소개:마이크로 서비스 A 인 터 페 이 스 는@restController 또는@Response Body 주석 으로 수식 하면 저 는 모두 마이크로 서비스 Bfeign 인터페이스 에서 String 을 사용 하여 받 아들 입 니 다.
특징:String 을 통 해 반환 인 자 를 받 아들 이 고 형식 이 일치 합 니 다.
단점:뒤쪽 호출 은 전환 이 필요 합 니 다.
코드 소개:
// A controller @restController
@PostMapping(value="/getAllQuestionBank",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public List<QuestionBankDto> getAllQuestionBank(){
return baseinfoQuestionMange.getAllQuestionBank();
}
// B feign String
@PostMapping(value="/baseinfo/getAllQuestionBank")
String getAllQuestionBank();
// B feign List<QuestionBankDto>
// , try catch
String questionBankInfo = baseInfoApi.getAllQuestionBank();
List<QuestionBankDto> mysqlQuestionBank = objectMapper.readValue(questionBankInfo,new TypeReference<ArrayList<QuestionBankDto>>(){});
![](https://s1.md5.ltd/image/c4b0c706265ba74f06e8878032ffb956.png)
springboot 의존 도 를 가 져 오기 만 하면 기본적으로 Jackson jar 가방 을 가 져 옵 니 다.
![](https://s1.md5.ltd/image/5080824b7ce0494ee8c7d41cc396cdf1.png)
주의사항:이 방식 을 사용 할 때 ObjectMapper 를 bean 용기 에 설정 해 야 합 니 다.
![](https://s1.md5.ltd/image/9b026d4c51aeec3bd4a2ba043c37ee9d.png)
3.총화
프로젝트 가 다 르 고 수요 가 다 르 며 두 가지 방식 은 누가 옳 고 그 른 지 에 대한 구분 이 없고 자신의 프로젝트 수요 에 따라 선택한다.
Feign 은 요 며칠 동안 겪 은 문제 들 을 사용 합 니 다.
일의 원인 은 내 가 paas 모듈 서 비 스 를 호출 하려 고 하 는 것 부터 시작 해 야 한다.
Feign 은 현재 튜 토리 얼 이 많 습 니 다.그리고 pom 을 도입 합 니 다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
자기 정의 인터페이스
@FeignClient(name = "weixinTokenClient", url = "https://qyapi.weixin.qq.com/cgi-bin")
public interface IWeiXinTokenClient {
/**
* token
* @param corpid
* @param corpsecret
* @return
*/
@RequestMapping(value = "/gettoken", method = RequestMethod.GET)
WeiXinTokenResultModel getToken(@RequestParam String corpid, @RequestParam String corpsecret);
}
test 류 테스트 를 통 해 완벽 하 게 되 돌아 갑 니 다.자신 이 비슷 한 프로젝트 를 썼 기 때문에 lemur-Huttp 를 볼 수 있 습 니 다.원리 가 대체적으로 일치 하고 생각 하 는 것 은 간단 합 니 다.하지만 뒤의 문 제 는 바로 나 옵 니 다.1.nacos 설정 에서 서 비 스 를 받 지 못 함
이 유 는 nacos 등록 서 비 스 는 lemur-admin 과 lemur-paas 와 같은 서비스 등급 의 서비스 만 등 록 했 기 때 문 입 니 다.서비스 주 소 를 얻 으 려 면 lemur-admin 서 비 스 를 사용 해 야 하지만 admin 에서 paas 인 터 페 이 스 를 호출 할 때
@FeignClient(value = "paasUserFacade", contextId = "lemur-paas", path = "/im/user")
public interface IPaasUserFacade extends IBaseController<PaasUserRequestModel> {
}
@FeignClient 주 해 는 value,name,contextId,serviceId 모두 name 이 므 로 nacos 주 소 를 가 져 오 는 곳 에 서 는 paas User Facade 로 일치 하여 받 을 수 없습니다.결국 N 번 코드 와 해결 방법 을 찾 지 못 했 습 니 다.자신 은 소스 코드 FeignClient Factory Bean 을 바 꾸 었 습 니 다.bean 을 등록 하 는 곳 에 서 는 value 를 사용 하 였 습 니 다.또한 contextId 로 별명 을 등록 하지 않 아 도 의미 가 크 지 않 고 이름 도 바 꿉 니 다.contextId 를 서비스 Id 로 생각 합 니 다.feign 은 target 을 통 해 주소 분석 을 하기 때문에 target 의 url 주 소 를 lemur-paas/im/user 로 바 꾸 면 됩 니 다.
<T> T getTarget() {
FeignContext context = this.applicationContext.getBean(FeignContext.class);
Feign.Builder builder = feign(context);
if (!StringUtils.hasText(this.url)) {
if (StringUtils.hasText(this.contextId) && !this.name.startsWith("http")){
this.url = "http://" + this.contextId;
}else if (StringUtils.hasText(this.contextId)){
this.url = this.contextId;
} else if (!this.name.startsWith("http")) {
this.url = "http://" + this.name;
}
else {
this.url = this.name;
}
this.url += cleanPath();
return (T) loadBalance(builder, context,
new HardCodedTarget<>(this.type, this.name, this.url));
}
if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
this.url = "http://" + this.url;
}
String url = this.url + cleanPath();
Client client = getOptional(context, Client.class);
if (client != null) {
if (client instanceof LoadBalancerFeignClient) {
// not load balancing because we have a url,
// but ribbon is on the classpath, so unwrap
client = ((LoadBalancerFeignClient) client).getDelegate();
}
builder.client(client);
}
Targeter targeter = get(context, Targeter.class);
return (T) targeter.target(this, builder, context,
new HardCodedTarget<>(this.type, this.name, url));
}
원본 코드 를 다 고 친 후에 서로 호출 할 수 있 는 셈 이다.2.fastjson 은 abstract class 를 지원 하지 않 습 니 다.관건 은 오 류 를 보고 하지 않 고 null 로 돌아 가 는 것 입 니 다.
풍경 이 통일 적 으로 돌아 오 는 것 은 모두 Response 대상 이 고 범 형 이기 때문에 결과 가 어떻게 호출 되 는 지 는 모두 null 입 니 다.호출 된 서비스 가 요청 을 받 고 돌아 오 는 것 을 보 세 요.이것 은 클 라 이언 트 의 문제 일 수 밖 에 없습니다.처음에 범 형 해석 문제 라 고 생각 하고 전체 호출 분석 체인 을 추적 하 였 습 니 다.
ReflectiveFeign.invoke->
SynchronousMethodHandler.invoke->
executeAndDecode->decode( )->
ResponseEntityDecoder.decode->
SpringDecoder.decode->
HttpMessageConverterExtractor.extractData( )->
FastJsonHttpMessageConverter( ).read(type,clazz,inputMessage)->
parseObject(is)
그리고 무엇 을 발 견 했 습 니까?fastjson 은 대상 을 예화 할 수 없습니다.제 가 가서 잘못 을 보고 하 겠 습 니 다.abstract 를 제거 하고 정상적으로 돌 아 왔 습 니 다.3.spring gateway 는 웹 을 지원 하지 않 습 니 다.
spring gateway 는 웹 flux 를 사용 하여 쓴 것 으로 웹 용기 가 아니 기 때문에 웹 을 도입 할 수 없습니다.feign 을 도입 할 때 웹 을 제거 해 야 합 니 다.그렇지 않 으 면 일어나 지 못 합 니 다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
또한 spring gateway 는 프로필 읽 기 를 지원 하지 않 습 니 다.같은 이유 로 j2cache 와 같은 파일 설정 방식 으로 는 읽 을 수 없습니다.이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Go 언어】interface 의 포인터로부터 메소드 호출할 수 없는 것은 왜?간결하게 말하면 「interface 를 가리키는 포인터는 interface 를 실장한 구조체의 포인터의 포인터가 되기 때문」입니다. 이것만으로는 잘 모르기 때문에 자세히 살펴 보겠습니다. interface의 Mamm...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.