首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring @GetMapping被忽略

Spring @GetMapping被忽略
EN

Stack Overflow用户
提问于 2020-01-21 10:51:03
回答 3查看 1.2K关注 0票数 1

我有以下控制器:

代码语言:javascript
复制
@RestController
@RequestMapping("/api/{brand}")
public class CarController {

  private final CarService carService;

  @Autowird
  public CarController(CarService carService) {
    this.carService = carService;
  }

  @GetMapping
  public Resources<Car> getCars(@PathVariable("brand") String brand) {
    return new Resources<>(carService.getCars(brand));
  }

  @GetMapping(value = "/{model}")
  public Car getModel(@PathVariable("brand") String brand, @PathVariable("model") String model) {
    return carService.getCar(brand, model);
  }
}

我希望对http://localhost:8080/api/bmw的http调用返回getCars方法的结果。相反,调用被委托给getModel方法。这将返回一个错误,因为没有{model}路径变量。

为什么我的http调用被委派给不正确的@GetMapping

在这里,您可以看到我通过hateoas下载的hateoas版本

INFO +- org.springframework.boot:spring-boot-starter-hateoas:jar:2.1.9.RELEASE:compile INFO +- org.springframework.boot:spring-boot-starter-web:jar:2.1.9.RELEASE:compile 信息- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.9.RELEASE:compile INFO + +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.26:compile 信息- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.26:compile INFO +- org.springframework.hateoas:spring-hateoas:jar:0.25.2.RELEASE:compile INFO - org.springframework.plugin:spring-plugin-core:jar:1.2.0.RELEASE:compile

我启用了Spring的mappings端点,甚至可以看到被忽略的端点是可用的:

代码语言:javascript
复制
{
  "handler": "public org.springframework.hateoas.Resources<com.example.Car> com.example.CarController.getCars(java.lang.String)",
  "predicate": "{GET /api/{brand}, produces [application/hal+json]}",
  "details": {
    "handlerMethod": {
      "className": "com.example.CarController",
      "name": "getCars",
      "descriptor": "(Ljava/lang/String;)Lorg/springframework/hateoas/Resources;"
    },
    "requestMappingConditions": {
      "consumes": [],
      "headers": [],
      "methods": [
        "GET"
      ],
      "params": [],
      "patterns": [
        "/api/{brand}"
      ],
      "produces": [
        {
          "mediaType": "application/hal+json",
          "negated": false
        }
      ]
    }
  }
}

编辑我添加了一个 拦截器 ,使我能够看到目标将是什么。

handlerMethod是正确的:

公共com.example.CarController.getCars(java.lang.String) org.springframework.hateoas.Resources

然而,我仍然得到以下错误:

内部服务器错误:类型字符串的方法参数缺少URI模板变量“model”

我无法理解这样一个事实:handlerMethod并不期望model参数,但是spring仍然会因为它而抛出一个错误。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-22 13:19:38

事实证明,@RestControllerAdvice是罪魁祸首:

代码语言:javascript
复制
@RestControllerAdvice(assignableTypes = {CarController.class})
public class InterceptModelPathParameterControllerAdvice {

  @Autowired
  CarService carService;

  @ModelAttribute
  public void validateModel(@PathVariable("model") String model) {
    if (!carService.isSupportedModel(model)) throw new RuntimeException("This model is not supprted by this application.");
  }
}

因为getCars方法没有@PathVariable("model"),所以抛出了异常。

票数 0
EN

Stack Overflow用户

发布于 2020-01-21 11:54:09

在您的示例中,@RequestMapping("/api/{ brand }")需要一个输入品牌,因为您在类级别上使用了注释,因此没有找到它。您可以通过以下方式纠正它:

代码语言:javascript
复制
@RestController
@RequestMapping("/api")
public class CarController {

  private final CarService carService;

  @Autowird
  public CarController(CarService carService) {
    this.carService = carService;
  }

  @GetMapping(value = "/{brand}")
  public Resources<Car> getCars(@PathVariable("brand") String brand) {
    return new Resources<>(carService.getCars(brand));
  }

  @GetMapping(value = "/{brand}/{model}")
  public Car getModel(@PathVariable("brand") String brand, @PathVariable("model") String model) {
    return carService.getCar(brand, model);
  }
}

因此,getCars()方法需要一个输入品牌,而getModel()则需要两个输入品牌和模型。希望能帮上忙!

票数 1
EN

Stack Overflow用户

发布于 2020-01-21 11:03:38

再次检查您的方法映射:

正如您所说的,您想要基于品牌调用gatCars方法,您必须在get映射中提供值,因此函数应该是:

代码语言:javascript
复制
 @GetMapping(value = "/{model}")
  public Resources<Car> getCars(@PathVariable("brand") String brand) {
    return new Resources<>(carService.getCars(brand));
  }

请求将转到getModel,因为它与签名匹配。更正getModel签名如下所示。

http://localhost:8080/api/bmw/x5

代码语言:javascript
复制
  @GetMapping(value = "/{model}/{brand}")
  public Car getModel(@PathVariable("brand") String brand, @PathVariable("model") String model) {
    return carService.getCar(brand, model);
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59839468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档