GET-запрос клиента Feign, выдает «Метод не разрешен: метод запроса« POST »не поддерживается» из микросервиса - PullRequest
0 голосов
/ 20 октября 2019

У меня есть приложение Vue.js с пружинным бэкэндом, которое делает звонки через клиент Feign в микросервис «заказов». У меня есть много запросов GET, которые работают нормально, используя @PathVariable (s), но у меня есть 1 запрос GET, в который может быть передано любое количество различных параметров URL, и я определил класс OrderListItemParameters и добавил его в запрос GET,передать параметры в микросервис. Я вижу, что запрос поступает в микросервис, но ему отказывают с ошибкой «org.zalando.problem.spring.common.AdviceTrait: метод не разрешен: метод запроса« POST »не поддерживается».

Я удостоверился, что параметры OrderListItemParameters, отправляемые клиентом симуляции, соответствуют параметрам OrderListItemParameters, ожидаемым на микросервисе. И нет никакого упоминания о POST ни в клиенте Feign, ни в микросервисе. У меня есть только конечные точки GET и PUT.

Java BackEnd для кода FrontEnd:

@RestController
@RequestMapping("/api")
public class OrdersResource {

    ## THIS WORKS NO PROBLEM
    @GetMapping("/order/{orderId}")
    public @ResponseBody
    ResponseEntity<?> order(@PathVariable int orderId) throws Exception {
        return ResponseEntity.ok(orderClient.order(orderId));
    }


    ## THIS ENDPOINT IS THE ONE THAT FAILS
    @GetMapping("/order/list")
    public @ResponseBody
    ResponseEntity<?> orders(OrderListItemParameters orderListItemParams) {
        return ResponseEntity
           .ok(orderClient.getOrderList(orderListItemParams));
    }
}

@Component
@AuthorizedUserFeignClient(name = "orders")
public interface OrderClient {

    ## THIS WORKS NO PROBLEM
    @RequestMapping(method = RequestMethod.GET, value = "/api/order/pg/{orderId}")
    String order(@PathVariable("orderId") int orderId);

    ## THIS ENDPOINT IS THE ONE THAT FAILS
    @RequestMapping(method = RequestMethod.GET, value = "/api/order/list")
    String getOrderList(OrderListItemParameters orderListItemParams);
}

OrderListItemParameters Класс передается как параметры URL: (это идентично в микросервисе)

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrderListItemParameters implements Serializable {

  private String searchPhrase;
  private String startDate;
  private String endDate;
  private ArrayList<String> sortKey;
  private ArrayList<String> sortValue;
  private Integer from;
  private Integer size;
}

(with getters, and setters) 

Микросервисный контроллер:

@Controller
@RequestMapping("/api")
public class OrderController {

  ## THIS WORKS NO PROBLEM
  @GetMapping("/order/pg/{orderId}")
  public @ResponseBody
  Order pgorder(@PathVariable int orderId) {
    return orderService.getPgOrderById(orderId);
  }

  ## THIS ENDPOINT IS THE ONE THAT FAILS
  @GetMapping("/order/list")
  public @ResponseBody
  ResponseEntity getOrderListItemsByMerchant(OrderListItemParameters orderListItemParams) {
    return orderService
        .getOrderListItemsByMerchant(orderListItemParams);
}

Вот картинка из журналов: Ясное указание запросов GET ... Logs

Любая помощь в выяснениипочему контроллер считает, что это запрос POST, было бы здорово.

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

Вот решение, которое в итоге заработало ...

#Resource
@GetMapping("/order/list")
public @ResponseBody 
ResponseEntity<?> getOrderListItemsByMerchant(
    @RequestParam Map<String, Object> params) {
    // method code
}

#Feign Client
@RequestMapping(method = RequestMethod.GET, value = "/api/order/list")
ResponseEntity<String> getOrderList(@RequestParam Map<String, Object> params);

#Microservice Controller
@GetMapping("/order/list")
public @ResponseBody
ResponseEntity getOrderListItemsByMerchant(OrderListItemParameters orderListItemParams) {
    // method code
}

Это позволяет мне получить URL с динамическими параметрами, а микросервис по-прежнему видит запрос как GET.

Было бы неплохо иметь один и тот же определенный объект по обе стороны запроса, но я не смог заставить @SpringQueryMap или @QueryMap работать вообще.

Я ненавижу Фейна.

0 голосов
/ 20 октября 2019

Предположительно, контроллер рассматривает ваш метод как POST из-за наличия тела запроса.

Я бы попробовал два варианта:

@GetMapping("/order/list")
public @ResponseBody ResponseEntity<?> getOrderListItemsByMerchant() {
    // method code
}

или

@PostMapping("/order/list")
public @ResponseBody ResponseEntity<?> getOrderListItemsByMerchant(OrderListItemParameters orderListItemParams) {
    // method code
}

UPDATE . Если вы все еще хотите использовать метод GET с телом, вам нужно изменить вызов метода в клиенте симуляции, явно пометив параметр:

@Component
@AuthorizedUserFeignClient(name = "orders")
public interface OrderClient {

    // feign methods

    @RequestMapping(method = RequestMethod.GET, value = "/api/order/list")
    @Headers(value = "Content-Type: application/json")
    ResponseEntity<String> getOrderList(@RequestParam("orderListItemParams") 
    OrderListItemParameters orderListItemParams);

}
...