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:
SecurityConfig
andSecurityWebApplicationInitializer
:SecurityConfig.java:
SecurityWebApplicationInitializer.java:
This is how my project looks now:
Main.java
is just for themaven-shade-plugin
, never mind it, it only contains the emptymain
method: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.xml
looks (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.