Mayank
Mayank

Reputation: 634

Spring Boot Controller not mapping

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)

Upvotes: 54

Views: 112205

Answers (16)

Matthew V Carey
Matthew V Carey

Reputation: 316

This issue will occur, due to other programming mistakes as well, things like having a service interface and a service implementation and having left off the instruction that tells the implementation that it implements the interface. Stupid mistake easy to do. Nothing works properly until you fix it. Not just bad spelling etc.

Upvotes: 0

iamharish15
iamharish15

Reputation: 1860

I too had a 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 the 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 should work with any spring boot version.

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

Upvotes: 117

Sanjay
Sanjay

Reputation: 21

In my case I added @ComponentScan("com.example.controller") to the SpringBoot application class.

Upvotes: 2

ytatichno
ytatichno

Reputation: 24

👋 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)

Upvotes: -1

Meet Shah
Meet Shah

Reputation: 818

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

Upvotes: 0

PunchyRascal
PunchyRascal

Reputation: 360

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.

Upvotes: 0

Areeba Fatima
Areeba Fatima

Reputation: 1

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

Upvotes: 0

vish213
vish213

Reputation: 786

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

Upvotes: 6

Gaurav Gupta
Gaurav Gupta

Reputation: 51

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);
    }
}

Upvotes: 5

Jayesh Patel
Jayesh Patel

Reputation: 61

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

Upvotes: 5

volkovs
volkovs

Reputation: 1183

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

Upvotes: 1

Chinmay Biswal
Chinmay Biswal

Reputation: 393

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.

Upvotes: 3

tsarenkotxt
tsarenkotxt

Reputation: 3499

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

Upvotes: 24

ptrk
ptrk

Reputation: 1840

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>

Upvotes: 6

Mayank
Mayank

Reputation: 634

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

Upvotes: 0

Darshan Mehta
Darshan Mehta

Reputation: 30849

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

Upvotes: 2

Related Questions