为了把一个带有独立Tomcat服务器的旧的Spring迁移到带有嵌入式Tomcat服务器的SpringBoot(1.5.22.RELEASE),我已经为这个问题挣扎了几天,我不确定我到底做错了什么,因为我仍然无法 bootstrap 它.

以下是web.xml的外观(位于src/main/webapp/WEB-INF中):

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.validateXml</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.SKIP_COMMENTS</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.LIBRARIES</param-name>
        <param-value>/WEB-INF/facelets/custom.taglib.xml</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.preferXHTML</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.expressionFactory</param-name>
        <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
    </context-param>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/META-INF/spring/root-context.xml
        </param-value>
    </context-param>

    <context-param>
        <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
        <param-value>com.sun.facelets.FaceletViewHandler</param-value>
    </context-param>

    <context-param>
        <param-name>org.richfaces.SKIN</param-name>
        <param-value>blueSky</param-value>
    </context-param>

    <context-param>
        <param-name>org.richfaces.CONTROL_SKINNING</param-name>
        <param-value>enable</param-value>
    </context-param>        <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>1000</param-value>
    </context-param>

    <filter>
        <filter-name>richfaces</filter-name>
        <display-name>RichFaces Filter</display-name>
        <filter-class>org.ajax4jsf.Filter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>richfaces</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>openEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>openEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>rest</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>rest</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/META-INF/spring/root-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/service/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>MyService.xhtml</welcome-file>
    </welcome-file-list> </web-app>

在大量搜索之后,我最终满足于实现ServletConextInitializer:

@Configuration
public class WebConfiguration implements ServletContextInitializer {
    private static final String FACES_SERVLET = "Faces Servlet";

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        
        TomcatContextCustomizer contextCustomizer = context -> context.addWelcomeFile("/MyService.xhtml");
        factory.addContextCustomizers(contextCustomizer);
        
        return factory;
    }
    
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        
        // Parameters
        servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "client");
        servletContext.setInitParameter("facelets.REFRESH_PERIOD", "1");
        servletContext.setInitParameter("com.sun.faces.validateXml", "true");
        servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
        servletContext.setInitParameter("facelets.DEVELOPMENT", "true");
        servletContext.setInitParameter("facelets.SKIP_COMMENTS", "true");
        servletContext.setInitParameter("facelets.LIBRARIES", "/WEB-INF/facelets/custom.taglib.xml");
        servletContext.setInitParameter("com.sun.faces.preferXHTML", "true");
        servletContext.setInitParameter("com.sun.faces.expressionFactory", "com.sun.el.ExpressionFactoryImpl");
        servletContext.setInitParameter("org.ajax4jsf.VIEW_HANDLERS", "com.sun.facelets.FaceletViewHandler");
        servletContext.setInitParameter("org.richfaces.SKIN", "blueSky");
        servletContext.setInitParameter("org.richfaces.CONTROL_SKINNING", "enable");
        servletContext.setInitParameter("log4jRefreshInterval", "1000");
        
        // Filters
        FilterRegistration.Dynamic richfacesFilter = servletContext.addFilter("richfaces", Filter.class);
        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE);
        richfacesFilter.addMappingForServletNames(dispatcherTypes, true, FACES_SERVLET);
        
        FilterRegistration.Dynamic openEntityManagerInViewFilter = servletContext.addFilter("openEntityManagerInViewFilter", OpenEntityManagerInViewFilter.class);
        openEntityManagerInViewFilter.addMappingForUrlPatterns(null, true, "/*");
        
        // Listeners
        servletContext.addListener(new ContextLoaderListener(rootContext));
        servletContext.addListener(new RequestContextListener());
        servletContext.addListener(new Log4jConfigListener());
        
        // Servlet
        ServletRegistration.Dynamic restServlet = servletContext.addServlet("rest", new DispatcherServlet(rootContext));
        restServlet.setLoadOnStartup(1);
        restServlet.addMapping("/rest/*");
        
        ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
        dispatcherServlet.setLoadOnStartup(1);
        dispatcherServlet.setInitParameter("contextAttribute", "org.springframework.web.context.WebApplicationContext.ROOT");
        dispatcherServlet.addMapping("/");
        
        ServletRegistration.Dynamic facesServlet = servletContext.addServlet(FACES_SERVLET, new FacesServlet());
        facesServlet.setLoadOnStartup(1);
        facesServlet.addMapping("*.xhtml", "*.html", "/faces/*", "*.faces");
    }
}

现在我的问题是,首先也是最重要的是监听程序,因为在启动过程中会抛出以下错误:

ERROR --- [ost-startStop-1] o.a.c.c.C.[.[.[/].log:182 - Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:296)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4697)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5165)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1412)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1402)
ERROR --- [ost-startStop-1] o.a.c.c.C.[.[.[/].log:182 - Exception sending context initialized event to listener instance of class [org.springframework.web.util.Log4jConfigListener]
java.lang.IllegalStateException: Cannot set web app root system property when WAR file is not expanded
        at org.springframework.web.util.WebUtils.setWebAppRootSystemProperty(WebUtils.java:156)
        at org.springframework.web.util.Log4jWebConfigurer.initLogging(Log4jWebConfigurer.java:119)
        at org.springframework.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:49)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4697)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5165)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1412)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1402)
ERROR --- [ost-startStop-1] o.a.c.c.StandardContext.log:180 - One or more listeners failed to start. Full details will be found in the appropriate container log file
ERROR --- [ost-startStop-1] o.a.c.c.StandardContext.log:180 - Context [] startup failed due to previous errors
INFO --- [ost-startStop-1] o.a.c.c.C.[.[.[/].log:180 - Shutting down log4j
ERROR --- [ost-startStop-1] o.a.c.c.C.[.[.[/].log:182 - Exception sending context destroyed event to listener instance of class [org.springframework.web.util.Log4jConfigListener]
java.lang.NoClassDefFoundError: org/apache/log4j/LogManager
        at org.springframework.util.Log4jConfigurer.shutdownLogging(Log4jConfigurer.java:123)
        at org.springframework.web.util.Log4jWebConfigurer.shutdownLogging(Log4jWebConfigurer.java:172)
        at org.springframework.web.util.Log4jConfigListener.contextDestroyed(Log4jConfigListener.java:54)
        at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4744)
        at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5403)
        at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:226)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1412)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1402)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.LogManager
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)

我认为SpringBoot已经运行了一个ConextLoaderListener,所以在阅读了此处有关该问题的内容后,我删除了它并删除了Log4jConfigListener:SEVERE: Exception org.springframework.web.util.Log4jConfigListener

现在它飞得更远了,但却卡在了这里:

ERROR --- [           main] o.a.c.c.C.[.[.[/].log:182 - StandardWrapper.Throwable
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
        at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:725)
        at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:239)
        at javax.faces.webapp.FacesServlet.init(FacesServlet.java:164)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1132)
        at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:976)
        at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4885)
        at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedContext.deferredLoadOnStartup(TomcatEmbeddedContext.java:77)
        at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.performDeferredLoadOnStartup(TomcatEmbeddedServletContainer.java:279)
        at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:206)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:289)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:145)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:300)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1082)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1071)
        at com.foo.Application.main(Application.java:18)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
ERROR --- [           main] o.a.c.c.C.[.[.[/].log:182 - Servlet [Faces Servlet] in web application [] threw load() exception
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
        at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:725)
        at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:239)
        at javax.faces.webapp.FacesServlet.init(FacesServlet.java:164)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1132)
        at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:976)
        at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4885)
        at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedContext.deferredLoadOnStartup(TomcatEmbeddedContext.java:77)
        at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.performDeferredLoadOnStartup(TomcatEmbeddedServletContainer.java:279)
        at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:206)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:289)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:145)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:300)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1082)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1071)
        at com.foo.Application.main(Application.java:18)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)

我不记得在哪里找到了它,但我看到了一条建议,将com.sun.faces.config.ConfigureListener添加为侦听器可以解决它.这足以让应用程序顺利 bootstrap ,然而,try 访问Web-UI时,我现在遇到了筛选器的问题:

ERROR --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].log:182 - StandardWrapper.Throwable
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
        at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:725)
        at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:239)
        at javax.faces.webapp.FacesServlet.init(FacesServlet.java:164)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1132)
        at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:779)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:134)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
ERROR --- [nio-8080-exec-3] o.a.c.c.C.[.[.[.[Faces Servlet].log:182 - Allocate exception for servlet [Faces Servlet]
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
        at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:725)
        at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:239)
        at javax.faces.webapp.FacesServlet.init(FacesServlet.java:164)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1132)
        at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:779)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:134)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
        

try 在没有筛选器的情况下运行,看看它是否可以启动,如果我可以解决这些问题,我最终发现了这个错误,我现在所在的位置:

ERROR --- [nio-8080-exec-1] f.viewhandler.handleRenderException:667 - Error Rendering View[/login.xhtml]
javax.faces.FacesException: Resources framework is not initialised, check web.xml for Filter configuration
        at org.ajax4jsf.resource.ResourceBuilderImpl.getWebXml(ResourceBuilderImpl.java:118)
        at org.ajax4jsf.resource.ResourceBuilderImpl.getUri(ResourceBuilderImpl.java:325)
        at org.ajax4jsf.resource.InternetResourceBase.getUri(InternetResourceBase.java:218)
        at org.richfaces.renderkit.html.MenuItemRendererBase.initializeResources(MenuItemRendererBase.java:188)
        at org.richfaces.renderkit.html.MenuItemRenderer.doEncodeEnd(MenuItemRenderer.java:191)
        at org.richfaces.renderkit.html.MenuItemRenderer.doEncodeEnd(MenuItemRenderer.java:319)
        at org.ajax4jsf.renderkit.RendererBase.encodeEnd(RendererBase.java:134)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:861)
        at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:281)
        at org.richfaces.renderkit.html.AbstractMenuRenderer.encodeItems(AbstractMenuRenderer.java:279)
        at org.richfaces.renderkit.html.AbstractMenuRenderer.processLayer(AbstractMenuRenderer.java:246)
        at org.richfaces.renderkit.html.AbstractMenuRenderer.encodeChildren(AbstractMenuRenderer.java:219)
        at org.richfaces.renderkit.html.DropDownMenuRendererBase.encodeChildren(DropDownMenuRendererBase.java:62)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:837)
        at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:277)
        at org.richfaces.renderkit.html.ToolBarGroupRenderer.renderChild(ToolBarGroupRenderer.java:74)
        at org.richfaces.renderkit.html.ToolBarGroupRenderer.encodeChildren(ToolBarGroupRenderer.java:56)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:837)
        at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:277)
        at org.richfaces.renderkit.html.ToolBarRendererBase.encodeChildren(ToolBarRendererBase.java:103)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:837)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:930)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:933)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:933)
        at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:578)
        at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
        at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)

    

这似乎几乎是有效的,因为我可以看到加载了很多库,页面确实试图呈现,但它到底缺少什么,我不知道.

推荐答案

注意到Rich Faces包中的WebXml.java是在表面下执行的,这似乎需要一个web.xml来读取属性.找不到任何替换类,所以我将Faces组件留在了web.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <!-- TODO - Not used by SpringBoot! But needed for richface 3.x with faces components for WebXml.java to set properties correctly -->
    <filter>
        <filter-name>richfaces</filter-name>
        <display-name>RichFaces Filter</display-name>
        <filter-class>org.ajax4jsf.Filter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>richfaces</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
</web-app>

但现在也将以下内容迁移(并在 bootstrap 时剥离了不必要的组件)到WebConfiguration:

public class WebConfiguration implements ServletContextInitializer {
    private static final String FACES_SERVLET = "Faces Servlet";
    
    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        
        TomcatContextCustomizer contextCustomizer = context -> context.addWelcomeFile("/MyService.xhtml");
        factory.addContextCustomizers(contextCustomizer);
        
        return factory;
    }
    
    @Override
    public void onStartup(ServletContext servletContext) {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        
        // Parameters
        servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "client");
        servletContext.setInitParameter("facelets.REFRESH_PERIOD", "1");
        servletContext.setInitParameter("com.sun.faces.validateXml", "true");
        servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
        servletContext.setInitParameter("facelets.DEVELOPMENT", "true");
        servletContext.setInitParameter("facelets.SKIP_COMMENTS", "true");
        servletContext.setInitParameter("facelets.LIBRARIES", "/WEB-INF/facelets/custom.taglib.xml");
        servletContext.setInitParameter("com.sun.faces.preferXHTML", "true");
        servletContext.setInitParameter("com.sun.faces.expressionFactory", "com.sun.el.ExpressionFactoryImpl");
        servletContext.setInitParameter("org.ajax4jsf.VIEW_HANDLERS", "com.sun.facelets.FaceletViewHandler");
        servletContext.setInitParameter("org.richfaces.SKIN", "blueSky");
        servletContext.setInitParameter("org.richfaces.CONTROL_SKINNING", "enable");
        servletContext.setInitParameter("log4jRefreshInterval", "1000");
        
        // Filters
        servletContext
           .addFilter("richfaces", new Filter())
           .addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, FACES_SERVLET);
        
        servletContext
           .addFilter("openEntityManagerInViewFilter", new OpenEntityManagerInViewFilter())
           .addMappingForUrlPatterns(null, false, "/*");
        
        // Listeners
        servletContext.addListener(new RequestContextListener());
        servletContext.addListener(new ConfigureListener());
        
        // Servlets
        ServletRegistration.Dynamic restServlet = servletContext.addServlet("rest", new DispatcherServlet(rootContext));
        restServlet.setLoadOnStartup(1);
        restServlet.addMapping("/rest/*");
        
        ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
        dispatcherServlet.setLoadOnStartup(1);
        dispatcherServlet.setInitParameter("contextAttribute", "org.springframework.web.context.WebApplicationContext.ROOT");
        dispatcherServlet.addMapping("/");
        
        ServletRegistration.Dynamic facesServlet = servletContext.addServlet(FACES_SERVLET, new FacesServlet());
        facesServlet.setLoadOnStartup(1);
        facesServlet.addMapping("*.xhtml", "*.html", "/faces/*", "*.faces");
    }
}

如果我将Rich Face升级到4.x甚至5.x,我可能完全可以在没有web.xml的情况下运行,但目前没有时间进行测试.

Java相关问答推荐

Java 22模式匹配不适用于记录模式匹配.给出汇编问题

我的scala文件失败了Scala.g4 ANTLR语法

填写文本字段后锁定PDF

Java 8中的多个字段和计数

@org.springframework.beans.factory.annotation.Autowired(required=true)-注入点有以下注释:-SpringBoot

XPages-在第二次点击按钮之前延迟

为什么在枚举中分支预测比函数调用快?

在模拟超类中设置非setter属性的值

SpringBoot+Java 17@Valid未验证POJO

有没有办法让扩展变得多态?

如何从日志(log)行中删除包名称?

我怎样才能让IntelliJ标记toString()的任何实现?

与IntArray相比,ArrayList<;Int>;对于大量元素的性能极差

EXCEL中的公式单元格显示#NAME?

IntelliJ IDEA依赖项工具窗口丢失

如何在不作为类出现的表上执行原生查询?

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

由于可为null,无法在kotlin中实现java接口

睡眠在 Spring Boot 中

一条Java记录可以保存多少个字段?