Spring Cloud Netflix Feign - ошибка 405 Метод запроса POST не поддерживается

Я пытаюсь создать REST-клиент, используя Feign для своего веб-сервиса. Веб-сервис построен на Spring 4 с конфигурацией xml beans.

Проект построен с помощью Maven и структурирован с использованием подмодулей.

foo-api
--- foo-api-client
------ src/main/java/foo/client
--------- FooClientFactory.java
------ pom.xml
--- foo-api-shared
------ src/main/java/foo/shared
--------- FooClient.java
------ pom.xml
--- foo-api-service
------ src/main
--------- /java/foo/service
------------ /config
--------------- FeignConfiguration.java
------------ /controller
--------------- FooController.java
--------- /webapp/WEB-INF
------------ spring.xml
------------ web.xml
--- pom.xml

Чтобы включить клиентов Feign, я создал аннотированный класс, включенный в конфигурации Spring xml.

spring.xml

...

<context:component-scan base-package="foo.service"/>

<context:annotation-config/>

<bean class="foo.service.config.FeignConfiguration" />

...

FeignConfiguration.java

package foo.service.config;

import org.springframework.cloud.netflix.feign.EnableFeignClients;

@EnableFeignClients
public class FeignConfiguration {
}

Затем я создал клиент Feign и настроил его с помощью аннотаций.

FooClient.java

package foo.shared;

import feign.Headers;
import feign.RequestLine;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("foo")
public interface FooClient {

    @RequestLine("GET /foo/v2/{id}")
    @Headers("Accept: " + MediaType.APPLICATION_JSON_VALUE)
    Object get(@PathVariable("id") String id);

}

Контроллер API реализует клиент Feign следующим образом

FooController.java

package foo.service.controller;

@Controller
@RequestMapping("/foo")
public class FooController implements FooClient {

    @Override
    @RequestMapping(value = "/v2/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody Object get(@PathVariable("id") String id) {
        ...
    }

    ...

}

Jar-файл модуля foo-api-client используется внешними клиентами в качестве зависимости для связи с REST-службой foo-api-service. Чтобы эти клиенты могли легко использовать api, был создан фабричный класс для создания экземпляра FooClient.

FooClientFactory.java

package foo.client;

import foo.shared.FooClient;
import feign.Feign;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

@Service
public class FooClientFactory {

    @Autowired
    private Environment env;

    public static final String SERVER_URL_PROPERTY = "foo.api.url";

    public FooClient build() {
        return Feign.builder()
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .target(FooClient.class, env.getProperty(SERVER_URL_PROPERTY));
    }

}

ПРОБЛЕМА Когда внешний клиент выполняет запрос к веб-службе foo с помощью FooClientFactory fooClientFactory.build().get("id");, возвращается ошибка 405. Вот журнал ответов на клиентской консоли:

ERROR [http-nio-8091-exec-1] --- [dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException: status 405 reading FooClient#get(String); content:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 405 Request method &apos;POST&apos; not supported</title>
</head>
<body><h2>HTTP ERROR 405</h2>
<p>Problem accessing /foo/v2/{id}. Reason:
<pre>    Request method &apos;POST&apos; not supported</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.3.7.v20160115</a><hr/>

</body>
</html>
] with root cause
feign.FeignException: status 405 reading FooClient#getOrder(String); content:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 405 Request method &apos;POST&apos; not supported</title>
</head>
<body><h2>HTTP ERROR 405</h2>
<p>Problem accessing /foo/v2/{id}. Reason:
<pre>    Request method &apos;POST&apos; not supported</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.3.7.v20160115</a><hr/>

</body>
</html>

Я искал такого рода проблемы в stackoverflow и других блогах, но не смог понять, что не так во всей настройке.

Любая идея?

Спасибо, Андреа


person andrearro88    schedule 25.03.2016    source источник
comment
Либо вы используете Spring Cloud с весенней загрузкой, либо используете ванильную симуляцию Netflix. В настоящее время нет смешивания и совпадения.   -  person spencergibb    schedule 26.03.2016
comment
Глядя на ваш код помимо @EnableFeignClients, вы используете vanilla feign, и поэтому аннотации Spring MVC не будут работать.   -  person spencergibb    schedule 26.03.2016


Ответы (1)


Я вижу два «фу» на пути.

@FeignClient("foo") и @RequestLine("GET /foo/v2/{id}")

что делает путь как /foo/foo/v2/{id}, однако ваш вызов должен быть /foo/v2/{id}.

Не могли бы вы попробовать, удалив "/ foo"

person Dhruv Saksena    schedule 31.08.2019