我有以下控制器:
@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端点,甚至可以看到被忽略的端点是可用的:
{
"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仍然会因为它而抛出一个错误。
发布于 2020-01-22 13:19:38
事实证明,@RestControllerAdvice是罪魁祸首:
@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"),所以抛出了异常。
发布于 2020-01-21 11:54:09
在您的示例中,@RequestMapping("/api/{ brand }")需要一个输入品牌,因为您在类级别上使用了注释,因此没有找到它。您可以通过以下方式纠正它:
@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()则需要两个输入品牌和模型。希望能帮上忙!
发布于 2020-01-21 11:03:38
再次检查您的方法映射:
正如您所说的,您想要基于品牌调用gatCars方法,您必须在get映射中提供值,因此函数应该是:
@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
@GetMapping(value = "/{model}/{brand}")
public Car getModel(@PathVariable("brand") String brand, @PathVariable("model") String model) {
return carService.getCar(brand, model);
}https://stackoverflow.com/questions/59839468
复制相似问题