Troubles running spring mvc java based configuration in idea local tomcat - java

I created to simple spring mvc configuration using java based configuration:
Config file:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.kitchen")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/kitchen/**").addResourceLocations("/kitchen/");
registry.addResourceHandler("/images/**").addResourceLocations("file:E:/Work/images/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Initializer:
public class WebMvcAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebMvcConfiguration.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Filter[] getServletFilters() {
return new Filter[]{new CORSFilter()};
}
}
Controller:
#Controller
public class IndexController {
#RequestMapping(value = "/")
public String getIndexPage() {
return "kitchen/index.html";
}
}
All files are located in same package. But when I try to deploy in tomcat, nothing is deployed. I am not good in configurations so I would like to ask maybe I forgot something more? I do not want to use web.xml, just plain java configuration.
Also there could be problem creating modules and artifacts in in Idea IDE I moved not a lot of time ogo to it from eclipse. so here is everithing a little bit different. Here are my configurations of project modules and artifacts, can you please tell me what could be problems in my situation?
Screens:

Related

Why does #ComponentScan behave differently for different configuration files?

I'm relatively new to Spring, and was following some examples.
During one of the examples I noticed that Spring wasn't mapping URI to methods.
I discovered that I put my #ComponentScan annotation on the wrong configuration class and fixed my problem.
So my question is why #ComponentScan works for one of these classes and not with the other?
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"org.zerock.controller"}) // This Works.
public class ServletConfig implements WebMvcConfigurer {
#Bean
public MultipartResolver multipartResolver(){
return new StandardServletMultipartResolver();
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
registry.viewResolver(resolver);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
#Configuration
//#ComponentScan(basePackages = {"org.zerock.controller"}) This Doesn't Work
public class RootConfig {
}
// How the two configuration classes are initialized
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{ServletConfig.class};
}
I've read that root config classes and servlet classes are set up differently in the application context hierarchy.
I suspect that has something to do with this, but I fail to see how that would cause this.
Javadoc for AbstractAnnotationConfigDispatcherServletInitializer recommend to implement:
getRootConfigClasses() -- for "root" application context (non-web infrastructure) configuration.
getServletConfigClasses() -- for DispatcherServlet application context (Spring MVC infrastructure) configuration.
If an application context hierarchy is not required, applications may return all configuration via getRootConfigClasses()
So a #ComponentScan on the RootConfig should work if there are no duplication on the ServletConfig level.
Could you post the error you get and all classes?
I recommend you to place the RootConfig in the root of you packages and use #ComponentScan without specifying base package.

Spring MVC Rest Controller 404

I am using a Spring MVC (5.3.7) app which has a Rest Controller. When I deploy the war using Intellij or manually on Tomcat 10.0 server, the get url gives me 404. After trying different Spring MVC configs which offcourse didn't work. Finally I resorted to the following config but still no luck
My DispatcherServletInitializer,
package com.luv2code.springdemo.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MySpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { DemoAppConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
My DemoConfig class as below used above,
#Configuration
#EnableWebMvc
#ComponentScan("com.luv2code.springdemo")
public class DemoAppConfig implements WebMvcConfigurer {
}
RestController class
#RestController
#RequestMapping("/api")
public class CustomerRestController {
#GetMapping("/customers")
public List<Customer> getCustomers() {
return customerService.getCustomers();
}
}
I have also added index.jsp in webapp folder in classpath which shows the right html (no 404 in route) when war is deployed. Meaning my MVC setup is fine but I don't know why I cannot reach the controller. I am using Java 11, here are the MAVEN dependencies list,
javax.servlet-api - 4.0.1
javax.servlet.jsp-api - 2.3.3
spring-webmvc - 5.3.7 Final
Packaging - war
Thanks for the suggestion. Downgrading to Tomcat#9 has done the work for me. Everything seems to be working now.
Here is the issue link which describes the incompatibility with Spring MVC 5.3.7 and Tomcat#10

Spring Boot Context Path Ignored With External Tomcat

I have set the context path for tomcat as follows:
#Component
public class CustomContainer implements
WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
#Override
public void customize(TomcatServletWebServerFactory factory) {
factory.setContextPath("/capripol");
factory.setPort(8080);
}
}
Navigating to localhost:8080/capripol works fine and I am prompted with my login screen, however after logging in my forms and controllers do not append to the context path, so instead of navigating to /capripol/MainMenu etc. they navigate to /MainMenu. How do I set the context path such that my form actions and controllers will be appended do it - why is the tomcat factory context path not setting?
Edit: My Application class
#SpringBootApplication
public class CapripolApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(CapripolApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CapripolApplication.class);
}
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/", "classpath:/images/")
.setCachePeriod(0);
}
}
}
A few ways to do it. You can add it to each controller, usefully if you want to change the context path
#Controller
#RequestMapping(value = "/foo")
public class bar{
#GetMapping(value = "/bar")
public void stuff(){
//doing stuff
}
}
Or you can put it in your application.properties / yml
server.servlet.contextPath=/foo/*
There are technically some other more round about ways to do it, especially if you are using an older version of Spring, but I would think the application properties is what you are looking for.

spring #crossorigin not working for the application

I'm new to spring. There is an existing spring project(Not maven, its a dynamic web project) on 4.3.9 version which is a working fine. I've written a new #RestController in the project and tried to access this controller from different machine. It throws me the
XMLHttpRequest cannot load http://<URL>. No 'Access-Control-Allow-Origin' header is present on the requested
There are only two files available for config here. There are no XML files for configuration. I'm confused where to add the cors filter config for the Application totally. I've added addCorsMappings in the AppInitializer Class. But still it doesnt work.
If I add #CrossOrigin(origins = "*", maxAge = 3600) it works on a controller only. I want for the total application.
#CrossOrigin(origins = "*", maxAge = 3600) -> This works only controller lvel
#RestController
public class CTUController {
// code
}
Kindly suggest me where to add
AppConfig class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "net.qdj.spring")
public class AppConfig{
}
AppInitializer
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
protected Class[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
protected Class[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
// Added for CORS -> Not working for application level
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Kindly advice me in this context
Use allowedOrigins.
registry.addMapping("/**").allowedOrigins("http://localhost:9000");
Instead of :
registry.addMapping("/**");

Spring 4 REST application using Java configuration (no xml) IllegalArgumentException [duplicate]

This question already has answers here:
java.lang.IllegalArgumentException: Failed to register servlet with name 'dispatcher'.Check if there is another servlet registered under the same name
(2 answers)
Closed 5 years ago.
This is driving me crazy. I've done a good bit of Spring coding but this is the first time that I'm trying to do all configuration in Java. I've searched all over stackoverflow and other places, and while others have seen this problem, none of their solutions have worked for me.
Here are my source files:
Initializer:
public class EnhancedCandidateInfoInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(EnhancedCandidateInfoInitializer.class);
#Override
protected Class<?>[] getRootConfigClasses() {
logger.info("##### getRootConfigClasses called - returning null #####");
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
logger.info("##### getServletConfigClasses called returning EnhancedCandidateInfoWebConfiguration.class #####");
return new Class[] { EnhancedCandidateInfoWebConfiguration.class };
}
#Override
protected String[] getServletMappings() {
logger.info("##### getServletMappings called #####");
return new String[] { "/" };
}
}
WebMvcConfiguration:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.mojorank.restapi"})
public class EnhancedCandidateInfoWebConfiguration extends WebMvcConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(EnhancedCandidateInfoWebConfiguration.class);
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
logger.info("#### My Configuration handler was called ####");
configurer.enable();
}
}
Controller:
#RestController
public class EnhanceCandidateInfoController {
#RequestMapping("/")
public String welcome() {//Welcome page, non-rest
return "Welcome to RestTemplate Example.";
}
#RequestMapping("/hello/{player}")
public Message message(#PathVariable String player) {//REST Endpoint.
Message msg = new Message(player, "Hello " + player);
return msg;
}
}
When I build and deploy the application to tomcat, I get the following exception stack trace:
Caused by: java.lang.IllegalArgumentException: Failed to register servlet with name 'dispatcher'.Check if there is another servlet registered under the same name.
at org.springframework.util.Assert.notNull(Assert.java:115)
at org.springframework.web.servlet.support.AbstractDispatcherServletInitializer.registerDispatcherServlet(AbstractDispatcherServletInitializer.java:98)
at org.springframework.web.servlet.support.AbstractDispatcherServletInitializer.onStartup(AbstractDispatcherServletInitializer.java:71)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5274)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
As I said, I've searched through stackoverflow and other places and found others that had my same problem, but when I tried to implement the proposed fixes, my problem remained. Thanks in advance for any help.
Change your WebMvcConfiguration method to this:
public class EnhancedCandidateInfoWebConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver ivr=new InternalResourceViewResolver();
ivr.setPrefix("/WEB-INF/jsp/");
ivr.setSuffix(".jsp");
ivr.setExposeContextBeansAsAttributes(true);
registry.viewResolver(ivr);
}
}

Categories