简体   繁体   中英

Why am I getting exception in my Spring Boot Application?

My Spring Boot Application,

在此处输入图片说明

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

After getting Whitelabel Error Page, I have mapped /error in one of my controllers,

@RestController
public class ResourceController {

    @RequestMapping("/home")
    String home() {
        return "Hello, Welcome!";
    }

    @RequestMapping("/error")
    String error() {
        return "Error occurred!";
    }
}

I am getting below exception as I mapped an /error ,

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 'basicErrorController' method 
org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
to { /error}: There is already 'resourceController' bean method
com.example.demo.controller.ResourceController#error() mapped.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at com.example.demo.DemoApplication.main(DemoApplication.java:10) [classes/:na]
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'basicErrorController' method 
org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
to { /error}: There is already 'resourceController' bean method

Update:

Followed User9123's solution but, I am still getting below page,

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Mar 03 03:27:22 BDT 2020
There was an unexpected error (type=None, status=999).
No message available

/error handler already defined in Spring Boot application. You can disable it:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;

@SpringBootApplication(exclude = {ErrorMvcAutoConfiguration.class})
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

or change your /error path to something else

The reason behind the error is in your ResourceController you have bind URL "/error" which is already used by Spring Boot BasicErrorController internally to show whitelabel error page.

You can change the requestMapping from URL "/error" to something else to get rid of the error. If you are interested in using the URL or customize default behaviour of Spring REST Error Handling than you can read more here.

https://mkyong.com/spring-boot/spring-rest-error-handling-example/

Spring is telling you that there is an ambiguous mapping. Since both com.example.demo.controller.ResourceController and org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController are having the same request mapping /error .

So, you can't keep /error in the ResourceController class.

Either you add a base request mapping path or change request mapping path on a particular API which is causing the ambiguous situation.

Example :

1st way : Add base mapping path on the controller which removes the ambiguous situation.

@RestController
@RequestMapping("/resource")
public class ResourceController {

    @RequestMapping("/home")
    String home() {
        return "Hello, Welcome!";
    }

    @RequestMapping("/error")
    String error() {
        return "Error occurred!";
    }
}

Note : In this case, all the APIs will have the paths starting with : <your url>/resource/<method request mapping path>

or

2nd way : Change request mapping path on a particular API which is causing the ambiguous situation.

For example :

@RestController
public class ResourceController {

    @RequestMapping("/home")
    String home() {
        return "Hello, Welcome!";
    }

    @RequestMapping("/resource/error")
    String error() {
        return "Error occurred!";
    }
}

Note : In this case, you have to use <your url>/resource/error to call error API.

In my opinion, I will recommend you to go for first approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM