我正在尝试将我的应用程序核心服务与我的 dispatcherservlet 和具有 @Controller 注释的类分开。我在这里阅读了很多关于 SO 的主题,但没有找到任何适合我的例子,只有关于根子层次结构、组件扫描包等的解释。
正如所有建议所说,在 appicationContext.xml 中我应该扫描除@Controller
类之外的所有组件,而在我的 DispatcherServlet-servlet.xml 中我应该只扫描@Controller
类。我这样做就像在这个@Service 构造了两次示例中一样。
所以我的应用程序构建成功,但是当我转到它的网页时,在 Chrome 中它告诉我This link appears to be broken.
这意味着该页面存在,否则 Tomcat 会告诉我这个The requested resource (/myapp) is not available.
我的配置一定有问题。可能是什么问题?这是我的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>
接下来是我的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>
下面是 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>
这是我的配置类
@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);
}
}
所以最后这里是我的服务器启动时的日志:
http://pastie.org/private/z8zv7jaddytxsgbh7oggw
我在服务器日志中看到 DispatcherServlet 定义了控制器 bean,但 applicationContext 映射了 RequestMappingHandlers。应该是这样吗?我不太确定整个画面应该如何工作,但根据我到目前为止所阅读的所有内容,这种上下文分离必须是正确的。但是,我的配置中的错误在哪里?
这是我的家庭控制器,非常基本
@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
}
}