52

I have used STS and now I am using IntelliJ Ultimate Edition but I am still getting the same output. My controller is not getting mapped thus showing 404 error. I am completely new to Spring Framework.

DemoApplication.java

package com.webservice.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
public class DemoApplication {

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

HelloController.java

package com.webservice.demo;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello(){
        return "Hey";
    }

}

Console Output

com.webservice.demo.DemoApplication      : Starting DemoApplication on XFT000159365001 with PID 11708 (started by Mayank Khursija in C:\Users\Mayank Khursija\IdeaProjects\demo)
    2017-07-19 12:59:46.150  INFO 11708 --- [           main] com.webservice.demo.DemoApplication      : No active profile set, falling back to default profiles: default
    2017-07-19 12:59:46.218  INFO 11708 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@238e3f: startup date [Wed Jul 19 12:59:46 IST 2017]; root of context hierarchy
    2017-07-19 12:59:47.821  INFO 11708 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8211 (http)
    2017-07-19 12:59:47.832  INFO 11708 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    2017-07-19 12:59:47.832  INFO 11708 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.15
    2017-07-19 12:59:47.944  INFO 11708 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2017-07-19 12:59:47.944  INFO 11708 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1728 ms
    2017-07-19 12:59:47.987  INFO 11708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
    2017-07-19 12:59:48.510  INFO 11708 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
    2017-07-19 12:59:48.519  INFO 11708 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
    2017-07-19 12:59:48.634  INFO 11708 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8211 (http)
    2017-07-19 12:59:48.638  INFO 11708 --- [           main] com.webservice.demo.DemoApplication      : Started DemoApplication in 2.869 seconds (JVM running for 3.44)
halfer
  • 19,824
  • 17
  • 99
  • 186
Mayank
  • 614
  • 1
  • 5
  • 11
  • 1
    Can you please add request, that returns 404 – Max Jul 19 '17 at 07:38
  • @Max By request you mean? – Mayank Jul 19 '17 at 07:40
  • 1
    The url you are using to access your controller's methods? – Afridi Jul 19 '17 at 07:41
  • @Max localhost:8211/hello – Mayank Jul 19 '17 at 07:42
  • 1
    and your application.properties file? did you defined any contextpath? or check the port address – Afridi Jul 19 '17 at 07:43
  • Use GetMapping instead of RequestMapping its more specific – Amit Gujarathi Jul 19 '17 at 07:44
  • @AmitGujarathi I think it doesn't matter here. if you are using RequestMapping, then it can be called by both GET & POST methods. – Afridi Jul 19 '17 at 07:45
  • @Afridi in my application.properties there is only server.port, I added coz my 8080 was busy, I think this doesnt have anything to do with problem – Mayank Jul 19 '17 at 07:46
  • Please read [Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers?](//meta.stackoverflow.com/q/326569) - the summary is that this is not an ideal way to address volunteers, and is probably counterproductive to obtaining answers. Please refrain from adding this to your questions. – halfer Jul 19 '17 at 11:43
  • @halfer I will keep that in mind. Thanks – Mayank Jul 19 '17 at 11:44
  • I have this same issue. Please check my code here. https://stackoverflow.com/questions/56015351/controller-not-getting-mapped – Ruchi Jha May 08 '19 at 03:29
  • Same problem. Help https://stackoverflow.com/questions/56015351/controller-not-getting-mapped – Ruchi Jha May 08 '19 at 03:31
  • I had put on the root and worked. If I would use a customized location, should I @Component? – Danilo Caetano Jul 29 '19 at 14:50
  • For lost google souls, `@RestController` is for API responses like JSON/XML while `@Controller` will lokk for that particular view. – piepi Jun 30 '21 at 22:18

14 Answers14

109

I too had the similar issue and was able to finally resolve it by correcting the source package structure following this

Your Controller classes are not scanned by the Component scanning. Your Controller classes must be nested below in package hierarchy to the main SpringApplication class having the main() method, then only it will be scanned and you should also see the RequestMappings listed in the console output while Spring Boot is getting started.

Tested on Spring Boot 1.5.8.RELEASE

But in case you prefer to use your own packaging structure, you can always use the @ComponentScan annotation to define your basePackages to scan.

iamharish15
  • 1,760
  • 1
  • 17
  • 20
  • 10
    Wow, what an unintuitive solution to a silent error. Thanks Spring. There should at least be some logging saying "hey, we noticed you don't have any controllers mapped. Here's one thing you should look at." I mean, sure, the actual application should probably be at the root of your hierarchy but if that's not the case for some reason, it looks like Spring just leaves you out to dry. – tytk Mar 05 '18 at 02:55
  • 2
    It's not necessary to maintain that package structure, but if you have your own packaging structure then make sure to annotate your Main Application class with `@ComponentScan` and mention your `basePackages` – iamharish15 Mar 05 '18 at 11:04
  • 1
    Better to use the correct structure, then use @ComponentScan. As mentioned in the doc. – Sumit Badsara Jun 15 '20 at 17:37
22

Because of DemoApplication.class and HelloController.class in the same package
Locate your main application class in a root package above other classes
Take look at Spring Boot documentation Locating the Main Application Class

Using a root package also allows component scan to apply only on your project.

For example, in your case it looks like below:

com.webservice.demo.DemoApplication
com.webservice.demo.controller.HelloController

tsarenkotxt
  • 3,231
  • 4
  • 22
  • 38
5

In my case, it was missing the dependency from pom.xml, otherwise everything compiled just fine. The 404 and missing mappings info from Spring logs were the only hints.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
ptrk
  • 1,800
  • 1
  • 15
  • 24
  • This is what worked for me. I also had to include the `tomcat` dependency though: ` org.springframework.boot spring-boot-starter-tomcat ` – sparkonhdfs Jun 06 '19 at 15:39
5

In my case, I was using @Controller instead of @RestController with @RequestMapping

vish213
  • 748
  • 3
  • 12
  • 27
4

I also had trouble with a similar issue and resolved it using the correct package structure as per below. After correction, it is working properly. e.g.

  • Spring Application Main Class is in package com.example
  • Controller Classes are in package com.example.controller
Uwe Allner
  • 3,399
  • 9
  • 35
  • 49
4

Adding @ComponentScan(com.webservice) in main class above @SpringBootApplication will resolve your problem. Refer below code

package com.webservice.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(com.webservice)
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
Gaurav Gupta
  • 43
  • 1
  • 1
2

In my opinion, this visibility problem comes when we leave the component scan to Spring which has a particular way of looking for the classes using standard convention. In this scenario as the Starter class(DemoApplication)is in com.webservice.demo package, putting Controller one level below will help Spring to find the classes using the default component scan mechanism. Putting HelloController under com.webservice.demo.controller should solve the issue.

Chinmay Biswal
  • 303
  • 5
  • 9
1

It depends on a couple of properties:

  • server.contextPath property in application properties. If it's set to any value then you need to append that in your request url. If there is no such property then add this line in application.properties server.contextPath=/
  • method property in @RequestMapping, there does not seem to be any value and hence, as per documentation, it should map to all the methods. However, if you want it to listen to any particular method then you can set it to let's say method = HttpMethod.GET
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
0

I found the answer to this. This was occurring because of security configuration which is updated in newer versions of Spring Framework. So i just changed my version from 1.5.4 to 1.3.2

Mayank
  • 614
  • 1
  • 5
  • 11
0

In my case I used wrong port for test request - Tomcat was started with several ones exposed (including one for monitoring /actuator).

volkovs
  • 1,153
  • 2
  • 11
  • 24
0

In my case I changed the package of configuration file. Moved it back to the original com.example.demo package and things started working.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Fernando Rocha Oct 20 '21 at 18:35
0

Another case might be that you accidentally put a Java class in a Kotlin sources directory as I did.

Wrong:

src/main
┕ kotlin       ← this is wrong for Java
  ┕ com
    ┕ example
        ┕ web
          ┕ Controller.class

Correct:

src/main
┕ java          ← changed 'kotlin' to 'java'
  ┕ com
    ┕ example
        ┕ web
          ┕ Controller.class

Because when in Kotlin sources directory, Java class won't get picked up.

PunchyRascal
  • 280
  • 2
  • 9
0

All other packages should be an extension of parent package then only spring boot app will scan them by default.

Other option will be to use @ComponentScan(com.webservice)

package structure

Meet Shah
  • 750
  • 7
  • 5
-1

I set up Spring Boot Security in Maven deps. And it automatically deny access to unlogged users also for login page if you haven't change rules for it. So I prefered my own security system and deleted this dependency.

If you want to use Spring Security. You can wrote WebSecurityConfig like this:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserService userService;

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf()
                    .disable()
                .authorizeRequests()
                    //Доступ только для не зарегистрированных пользователей
                    .antMatchers("/registration").not().fullyAuthenticated()
                    //Доступ только для пользователей с ролью Администратор
                    .antMatchers("/admin/**").hasRole("ADMIN")
                    .antMatchers("/news").hasRole("USER")
                    //Доступ разрешен всем пользователей
                    .antMatchers("/", "/resources/**").permitAll()
                //Все остальные страницы требуют аутентификации
                .anyRequest().authenticated()
                .and()
                    //Настройка для входа в систему
                    .formLogin()
                    .loginPage("/login")
                    //Перенарпавление на главную страницу после успешного входа
                    .defaultSuccessUrl("/")
                    .permitAll()
                .and()
                    .logout()
                    .permitAll()
                    .logoutSuccessUrl("/");
    }

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
    }
}

from [https://habr.com/ru/post/482552/] (in russian)

ytatichno
  • 14
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 06 '22 at 09:39