我有一个带有Spring后端的Vue.js应用,该应用通过Feign Client调用“订单”微服务。我有许多使用@PathVariable()都可以正常工作的GET请求,但是我有1个GET请求,可以将任何数量的不同URL参数传递给它,并且已经定义了OrderListItemParameters类并将其添加到GET请求中,将参数传递给微服务。我可以看到该请求正在发送到微服务,但是由于“ org.zalando.problem.spring.common.AdviceTrait:不允许的方法:请求方法'POST'不支持”错误而被拒绝。
我已经确保伪装客户端发送的OrderListItemParameters与微服务期望的OrderListItemParameters相匹配。 Feign客户端或微服务中都没有提及POST。我只有GET和PUT端点。
用于前端代码的Java后端:
@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);
}
任何帮助弄清楚控制器为何认为这是POST请求的人都会很棒。
答案 0 :(得分:0)
大概是由于请求正文的存在,控制器将您的方法视为POST。
我会尝试两种选择:
@GetMapping("/order/list")
public @ResponseBody ResponseEntity<?> getOrderListItemsByMerchant() {
// method code
}
或
@PostMapping("/order/list")
public @ResponseBody ResponseEntity<?> getOrderListItemsByMerchant(OrderListItemParameters orderListItemParams) {
// method code
}
UPDATE 。如果仍然希望将GET方法与body一起使用,则需要通过显式标记参数来更改伪客户端中的方法调用:
@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);
}
答案 1 :(得分:0)
这是最终可以解决的解决方案...
#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正常工作。
我讨厌假装。
答案 2 :(得分:0)
该问题应该通过更改来解决:
String getOrderList(OrderListItemParameters orderListItemParams);
收件人:
String getOrderList(@SpringQueryMap OrderListItemParameters orderListItemParams);
问题在于,使用没有参数的数据类会将其映射到GET请求无法编码的主体请求;从而将请求转换为客户端中的POST,但在未实现该动词的正确服务器上以405失败。
在普通的Feign中,应该使用@QueryMap而不是Spring集成。 More detailed information can be found here