I'm trying to access a http://localhost:8088/test_war_exploded/home/hello but get 404 error. I can't figure out why.
Directory structure:
root
src
main
java
test
config
DbConfig.java
MyAppInitializer.java
WebConfig.java
HomeController.java
WebConfig.java:
@Configuration
@ComponentScan("test")
@EnableWebMvc
@EnableTransactionManagement
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableJpaRepositories(basePackages = "test",
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager")
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".html");
return bean;
}
}
MyAppInitializer.java:
public class MyAppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
public void onStartup(final ServletContext sc) throws ServletException {
System.out.println("onStartup!");
AnnotationConfigWebApplicationContext root =
new AnnotationConfigWebApplicationContext();
root.register(WebConfig.class);
root.setServletContext(sc);
root.scan("test");
//sc.addListener(new ContextLoaderListener(root));
ServletRegistration.Dynamic appServlet =
sc.addServlet("dispatcher", new DispatcherServlet(new GenericWebApplicationContext()));
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/");
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
HomeController.java:
@RestController
@RequestMapping("/home")
public class HomeController {
@GetMapping(value = "/hello")
public String hello() {
return "Hello";
}
}
The app gets deployed with no errors in server / IDE log. During deployment onStartup gets printed in console, meaning the code in MyAppInitializer gets executed.
I figured it out. The problem was that I didn't have an initializer class. I added two classes:
SecurityConfigandSecurityWebApplicationInitializer:SecurityConfig.java:
SecurityWebApplicationInitializer.java:
This is how my project looks now:
Main.javais just for themaven-shade-plugin, never mind it, it only contains the emptymainmethod:Main.java:
My other classes (updated). I removed database config class for simplicity. If you don't need a database, you can just copypaste classes from this answer and it should work fine:
MyAppInitializer.java:
WebConfig.java:
HomeController.java:
TestController.java:
I removed view resolvers from config classes, because I intend to only use rest controllers as an API provider. Thanks for coming to my TED talk.
PS Here's how the
pom.xmllooks (it seems to be important because with different poms Intellij doesn't auto generate war-exploded artifact):Once you've configured Tomcat Local, you can change this pom.xml.
If you also want database support, add this file to config package:
PS If you also use Idea Intellij, follow this video to deploy the application on Tomcat.