I've just created my controller, however when I try to start my application I get the error mentioned in the title.
I've spent some time messing around with my controller and cannot see any duplicated mappings so not entirely sure whats going wrong. Below is my controller:
@Controller
public class CSPServerController {
@Autowired
ServerService serverService;
@Autowired
AuditLogService auditLogService;
@RequestMapping(name = "/servers", method = RequestMethod.GET)
@PreAuthorize("hasRole(T(com.nathanenglish.serverlldmanagementtool.config.GlobalConfig).RoleReadOnly)")
public String loadServers(Model model){
model.addAttribute("servers",serverService.getAll());
return "servers";
}
@RequestMapping(name = "/servers/new", method = RequestMethod.GET)
@PreAuthorize("hasRole(T(com.nathanenglish.serverlldmanagementtool.config.GlobalConfig).RoleEdit)")
public String newServer(Model model){
model.addAttribute("server", new Server());
model.addAttribute("auditLog", new AuditLog());
return "server";
}
@RequestMapping(name = "/servers/{id}", method = RequestMethod.GET)
@PreAuthorize("hasRole(T(com.nathanenglish.serverlldmanagementtool.config.GlobalConfig).RoleEdit)")
public String getServer(@PathVariable Long id, Model model){
model.addAttribute("server", serverService.getById(id));
model.addAttribute("auditLog", new AuditLog());
return "server";
}
@RequestMapping(name = "/servers/save", method = RequestMethod.POST)
@PreAuthorize("hasRole(T(com.nathanenglish.serverlldmanagementtool.config.GlobalConfig).RoleEdit)")
public String saveServer(Model model, @Valid Server server, @Valid AuditLog auditLog, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "server";
}
serverService.save(server);
auditLogService.save(auditLog);
return "redirect:/servers";
}
@RequestMapping(name = "/servers/delete/{id}", method = RequestMethod.GET)
@PreAuthorize("hasRole(T(com.nathanenglish.serverlldmanagementtool.config.GlobalConfig).RoleEdit)")
public String deleteServer(@PathVariable Long id, Model model){
serverService.deleteByID(id);
return "redirect:/servers";
}
}
Error Log:
*org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'CSPServerController' method
public java.lang.String com.nathanenglish.serverlldmanagementtool.controller.CSPServerController.getServer(java.lang.Long,org.springframework.ui.Model)
to {[],methods=[GET]}: There is already 'CSPServerController' bean method
public java.lang.String com.nathanenglish.serverlldmanagementtool.controller.CSPServerController.newServer(org.springframework.ui.Model) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at com.nathanenglish.serverlldmanagementtool.ServerLldManagementToolApplication.main(ServerLldManagementToolApplication.java:12) [classes/:na]
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'CSPServerController' method
public java.lang.String com.nathanenglish.serverlldmanagementtool.controller.CSPServerController.getServer(java.lang.Long,org.springframework.ui.Model)
to {[],methods=[GET]}: There is already 'CSPServerController' bean method
public java.lang.String com.nathanenglish.serverlldmanagementtool.controller.CSPServerController.newServer(org.springframework.ui.Model) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:580) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:544) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:265) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$1(AbstractHandlerMethodMapping.java:250) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_171]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:248) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:218) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:188) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:129) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1765) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
... 16 common frames omitted*
In all your request mappings, you have incorrectly used name
instead of value
@RequestMapping(name = "/servers/{id}", method = RequestMethod.GET)
should be
@RequestMapping(value = "/servers/{id}", method = RequestMethod.GET)
As a result of this, both getServer and newServer were trying to map to the same URL - GET /
which is not allowed.
Generally, this error comes when you put the same URL mapping with in the same controller or any other controller class for the same method Types. For example -
@GetMapping(value = "/asset", produces = { MediaTypes.APPLICATION_JSON_UTF8 })
ResponseEntity<ApiResponse<Object>> getAssetData(String assetId) {}
@GetMapping(value = "/asset", produces = { MediaTypes.APPLICATION_JSON_UTF8 })
ResponseEntity<ApiResponse<Object>> getAllAssets() {}
In this case, we are using the same method type with the same URL mappings which are wrong. This mapping should be unique within all controllers for the same method types.
You can use the same mapping only for HTTP method types like GET, POST, PUT, DELETE but only once.
But
if Accept Header value (produces) is different for the same mapping than there is no problem for same method also.
@GetMapping(value = "/asset", produces = { MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<ApiResponse<Object>> getAssetData(String assetId) {}
@GetMapping(value = "/asset", produces = { MediaType.APPLICATION_XML_VALUE })
ResponseEntity<ApiResponse<Object>> getAssetData(String assetId) {}
It will work fine because "produces" value is different for even the same URL mapping.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With