我用JavaConfig编写了一个小型SpringMVC应用程序。它在Tomcat上运行得很好,但在JBossEAP6.2上运行得不好。它在JBoss上成功部署,但当我请求Spring MVC定义的任何页面时,浏览器中出现404错误时,我会收到此警告。
< code > WARN[org . spring framework . web . servlet . pagenotfound](http-/127 . 0 . 0 . 1:8080-1)在DispatcherServlet中,未找到名为“dispatcher”的URI为[/example-web/pages/login.jsp]的HTTP请求的映射
在这里你可以看到我的代码:
public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/*" };
}
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter() };
}
}
下面是我的Spring MVC配置:
@EnableWebMvc
@ComponentScan("com.spring.example.w.controller")
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
}
和根配置:
@Configuration
@ComponentScan
public class RootConfiguration {
}
在部署过程中,我可以在日志中看到请求确实得到了映射:
INFO [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] (ServerService Thread Pool -- 71) Mapped "{[/start],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView com.spring.example.w.controller.StartController.handleStart() throws javax.servlet.ServletException,java.io.IOException
INFO [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (ServerService Thread Pool -- 71) Mapped URL path [/login] onto handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
INFO [org.springframework.web.context.ContextLoader] (ServerService Thread Pool -- 71) Root WebApplicationContext: initialization completed in 2530 ms
INFO [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/example-web]] (ServerService Thread Pool -- 71) Initializing Spring FrameworkServlet 'dispatcher'
INFO [org.springframework.web.servlet.DispatcherServlet] (ServerService Thread Pool -- 71) FrameworkServlet 'dispatcher': initialization started
关于为什么我得到404错误和这个警告的任何帮助都非常感谢。我应该再次强调它正在Tomcat上工作。提前感谢。
在阅读SivaLabs的教程时,在JBoss上运行与tomcat配合良好的应用程序时遇到了这样的问题。通过将DispatcherServlet映射更改为“/app/*”来解决问题。您也可以尝试实现WebApplicationInitializer而不是使用抽象类。以下是示例:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/"); // i have a more or less big website, and can't see advantages by using "/*" mapping, this can be also a problem.
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocations("ua.company.config.WebConfig", "ua.company.config.PersistenceConfig", "ua.company.config.SecurityConfig");
return context;
}
您可能正在体验Red Hatbug1094248,"默认servlet无法在没有web.xml的情况下被覆盖"。此问题显然影响EAP 6.2、6.3和6.4.0。来自bug报告:
将Spring dispatcher servlet映射到url模式“/”在程序上不起作用。换句话说,用Java代码覆盖默认servlet是不可能的。
后果:许多用户将Spring的DispatcherServlet映射到“/”,这在web.xml.中完成时效果很好。但是,当此配置以编程方式完成时,默认servlet首先绑定到“/”。这阻止了稍后绑定DispatcherServlet。Spring控制器没有映射,404被检索。
解决方法(如果有):使用 web.xml 配置或以编程方式将调度程序 servlet 映射到某个特定的 URL 模式。例如 “/调度程序/*”
对于EAP 6.4,这在版本6.4.1中得到了修复。我不知道EAP的早期版本。该bug已于2017年1月修复,因此您需要查找之后发布的修补程序。
有权访问Red Hat解决方案知识库的人也可能希望查看解决方案1211203。