I'm trying to separate my application core services from my dispatcherservlet and classes that have @Controller annotation. I've read numerous topic here on SO but didn't find any example that suits my case, only explanations about root-child hierarchy, component scan packages and so on.
As all the suggestions tell that in appicationContext.xml I should scan all components except @Controller
classes and in my DispatcherServlet-servlet.xml I should scan ONLY for @Controller
classes. I did it just like in this @Service are constructed twice example.
So my application builds successfully, but when i go to it's webpage, in Chrome it tells me that This link appears to be broken.
This means that the page exists, otherwise Tomcat would tell me that this The requested resource (/myapp) is not available.
There must be something wrong in my configurations. What may be the problem?
Here is my applicationContext.xml
<beans <!-- omitting namespaces for readability --> >
<!-- Scans within the base package of the application for @Components to configure as beans -->
<!-- @Controller, @Service, @Configuration, etc. -->
<context:component-scan base-package="com.myapp">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />
<mvc:resources mapping="/static/**" location="/" />
<mvc:default-servlet-handler />
<jpa:repositories base-package="com.myapp.repo" />
</beans>
Next is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app <!-- omitting namespaces for readability -->>
<display-name>My application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
classpath:spring-security.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Ensure UTF-8 encoded pages so that certain characters are displayed and submitted correctly -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Enables support for DELETE and PUT request methods with web browser clients -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/view/error/404.jsp</location>
</error-page>
</web-app>
Below is DispatcherServlet-servlet.xml
<beans <!-- omitting namespaces for readability -->>
<context:component-scan base-package="com.myapp.mvc" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans>
Here is my configuration class
@Configuration
@ImportResource("classpath:applicationContext.xml")
@PropertySource("classpath:images.properties")
public class AppConfig implements InitializingBean {
@Inject
ServletContext context;
// Resolve logical view names to .jsp resources in the /WEB-INF/views directory
@Bean
ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
// Configure the multipart resolver
@Bean
CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
// multipartResolver.setMaxUploadSize(2_202_009);
return multipartResolver;
}
@Override
public void afterPropertiesSet() throws Exception {
File logoImgPreview = new File("resources/img/image_footer_logo_preview.jpg");
BufferedImage bufImgPreview = ImageIO.read(logoImgPreview);
context.setAttribute("watermark_preview", bufImgPreview);
}
}
So and lastly here is the log when my server starts:
http://pastie.org/private/z8zv7jaddytxsgbh7oggw
What I see in the server logs that DispatcherServlet defines the controller beans but applicationContext maps RequestMappingHandlers. Should it be like so? I'm not really sure about the whole picture how everything should work, but according to everything I've read till now, this kind of context separating must be correct. But then where are the mistakes in my configurations?
Here is my homecontroller which is very basic
@Controller
public class HomeController {
private static Logger log = LoggerFactory.getLogger("com.myapp.mvc.HomeController");
@RequestMapping("/")
public String home() {
log.debug("Requesting index page");
return "index"; // it returns to index.jsp
}
}