I created a base Spring controller for my latest web app project that I inherit from for all my basic CRUD controllers, called CrudController:
class CrudController<T, K extends Serializable>
T is the Entity type, and K is the key used for that type (pretty much the parameters needed for Spring's CrudRepository). I create a rest controller by extending it, like so:
@RestController
@RequestMapping(path = "/hats")
public class HatController extends CrudController<Hat, Integer> {
}
Everything works great, except for the method that gets the list of items, /hats
. With this method, I get a 405 Method Not Allowed. When I look at the logging that was done during startup, I can see that RequestMappingHandlerMapping did not map {[/hats],methods=[GET]}
but it did map the other four methods in the controller. Here is the code for the method that isn't being mapped:
@RequestMapping(method = RequestMethod.GET)
public HttpEntity<?> getAll() {
Iterable<T> result = controllerRepository.findAll();
return new ResponseEntity<Object>(result, HttpStatus.OK);
}
After much experimentation, I have discovered that if I add a parameter to the getAll method that is one of the class parameter types, the method will get mapped. Check this very similar code out:
@RequestMapping(method = RequestMethod.GET)
public HttpEntity<?> getAll(K dontuse) {
Iterable<T> result = controllerRepository.findAll();
return new ResponseEntity<Object>(result, HttpStatus.OK);
}
With that small code change, the /find
call works fine. I can keep my dummy parameter in there and everything will work, but it smells.
Any ideas? A simplified project that replicates the issue can be found here:
答案 0 :(得分:4)
目前Java中存在一个错误,请参阅错误报告here和here,其中Class#getDeclaredMethods()
为声明为包的超类的每个继承方法返回一个桥Method
- 私人的。基于javadoc,它不应该这样做。
这混淆了Spring MVC对@Controller
带注释的类和处理程序方法的检查。在这个答案中详细介绍将不会非常有用,但您可以查看处理它的代码here。
最简单的解决方案是将您的CrudRepository
课程声明为public
。
public class CrudController<T, K extends Serializable>