关于fegin调用其他服务的问题Method get not annotated with HTTP method type (ex. GET, POST);

本文介绍在Spring Cloud中使用Feign进行远程服务调用时遇到的问题及解决方法,详细解析Feign的契约模式配置,避免Method not annotated with HTTP method type错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发中我使用的是SpringCloud,有个服务就是要调用其它服务里的读取文件的接口,于是我使用fegin来进行调用。

package com.becypress.card.feign;

import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Map;
/**
 * @Description: 通过fegin远程调用读取excel文件接口
 * @Param:
 * @return:
 * @Author: zp
 * @Date: 2019/12/28
 */
@FeignClient(value = "hzs-admin", path = "/api/file")
public interface ReadExcelFileClient
{
    @GetMapping("/{id}")
    ResponseEntity<Map<String, Object>> get(@Param("id") String id);  //查询文件地址

}

当实际调用时报错了:

not annotated with HTTP method type (ex. GET, POST)

百思不得其解,明明有@GetMapping("/{id}") 注解啊,咋回事?于是百度了一圈发现,原来fegin这玩意儿它有个契约,契约规定fegin默认使用 @RequestLine("")注解。像这样:

@RequestLine("GET /{id}")

于是我把代码改了一下,可以正常调用其他服务了。

/**
 * @Description: 通过fegin远程调用读取excel文件接口
 * @Param:
 * @return:
 * @Author: zp
 * @Date: 2019/12/28
 */
@FeignClient(value = "hzs-admin", path = "/api/file")
public interface ReadExcelFileClient
{
    @RequestLine("GET /{id}")
    ResponseEntity<Map<String, Object>> get(@Param("id") String id);  //查询文件地址


}
出现这种情况的原因是:

1.不支持@GetMapping这样的混合注解只能使用@RequestMapping(value="/simple/{id}",method=RequestMethod.GET)这种方式来实现混合注解。

2.对于url路径上的PathVariable属性必须要有默认值,否者会报PathVariable annotation was empty on param 0.

3.这个就是当时我纠结了两个小时的坑,最后翻看Contract.Default()的源码才明白,如果FeignClient想要使用feign自己定义的注解,需要在configuration中配置feign的契约模式,因为其默认采用的时sping的注解方式,所以会不识别feign的注解,导致Method getServiceInfoByserviceName  not annotated with HTTP method type (ex. GET, POST)。

这种异常情况下的解决方法有两种:

一种就是使用sping默认的注解方式

@RequestMapping(value="/eureka/apps/{serviceName}", method=RequestMethod.GET)@PathVariable("必须有值")

eg:

@RequestMapping(value="/eureka/apps/{serviceName}", method=RequestMethod.GET)

public String getServiceInfoByserviceName(@PathVariable("serviceName") String serviceName) ;
}

另外一种就是在configuration中配置feign的契约模式

eg:

@Configuration
public class FeignConfiguration {
    //Contract feign的默认契约
    @Bean
    public Contract feignContract() {
        return Contract.Default();
    }

}


 

如果不想使用fegin默认的契约,可以自己写个fegin的配置类。不过,在写之前先了解一下fegin契约是个什么鬼:

Fegin配置文件是这样的:

@Configuration
public class FeignClientUserServiceConfiguration {
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("user", "password");
    }    
}
 

中间部分

    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

显示项目用的是fegin的契约。

默认契约用的是@RequestLine注解。RequestLine 如果不知名POST还是GET 就会报 Method get not annotated with HTTP method type (ex. GET, POST)。

那如果要用@RequestMapping 注解怎么办呢,把上面的红色部分的配置删掉,那样Fegin会使用SpringMvcContract契约。问题就解决了。

注意:

  • fegin 注解只能在接口上使用
  • 如果配置了上述的fegin配置类,则当前服务下只要是使用fegin调用远程服务的注解都应遵循此契约。不能有一个fegin接口使用springMVC注解,而另一个又使用 @RequestLine("")注解。
  • FeignClient注解中value、serviceId、name这三个值是一个意思,它默认取第一个

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值