0

鉴于现有web.xml

<?xml version="1.0" encoding="UTF-8"?>

<display-name>/</display-name>

<listener><listener-class>m.Web.startup.Listener</listener-class></listener>
<listener><listener-class>m.Store.Listener</listener-class></listener>

<session-config>
    <session-timeout>30</session-timeout>
</session-config>                                          

<servlet-mapping>
    <servlet-name>mmm.com.dispatcher.servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>mmm.com.dispatcher.servlet</servlet-name>
    <servlet-class>m.Web.startup.DispatcherServlet</servlet-class>
    
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.XmlWebApplicationContext</param-value>
    </init-param>
    
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/Web/config/ConfigWeb.xml
            classpath:/Auth/config/ConfigAuth.xml
            classpath:/Assets/config/ConfigAssets.xml
            classpath:/Accounts/config/ConfigAccounts.xml
            classpath:/App/config/ConfigApp.xml
            classpath:/Accounts/config/ConfigAccounts.xml
            classpath:/Store/config/ConfigStore.xml
        </param-value>
    </init-param>
    
    <load-on-startup>1</load-on-startup>
</servlet>

我已经添加:

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>8.0.48</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>8.0.48</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-logging-juli</artifactId>
    <version>8.0.48</version>
</dependency>

并试图做:

private static void c() throws LifecycleException {
    File tmpDir = new File(System.getProperty("java.io.tmpdir"));

    Tomcat tomcat = new Tomcat();
    tomcat.setBaseDir(tmpDir.getAbsolutePath());
    tomcat.setPort(8080);
    
    XmlWebApplicationContext context = new XmlWebApplicationContext();
    
    DispatcherServlet servlet = new DispatcherServlet(context);
    
    servlet.setContextConfigLocation("""
        classpath:/Web/config/ConfigWeb.xml
        classpath:/Auth/config/ConfigAuth.xml
        classpath:/Assets/config/ConfigAssets.xml
        classpath:/Accounts/config/ConfigAccounts.xml
        classpath:/App/config/ConfigApp.xml
        classpath:/Accounts/config/ConfigAccounts.xml
        classpath:/Store/config/ConfigStore.xml
    """);
    
    Tomcat.addServlet(tomcat.addContext(tomcat.getHost(), "/", tmpDir.getAbsolutePath()), "mmm.com.dispatcher.servlet", servlet);

    new m.Web.startup.Listener();
    new m.Store.Listener();
    
    tomcat.start();
    
    tomcat.getServer().await();
}

但不工作。

服务器启动,但有几件事无法正常工作。localhost:8080导致错误页面。

也试过:

public static void e() throws LifecycleException {
    Tomcat tomcat = new Tomcat() {
        @Override
        public Context addWebapp(String contextPath, String docBase) throws ServletException {
            Context context = null;
            try {
                context = new StandardContext();
                context.setName(contextPath);
                context.setPath(contextPath);
                context.setDocBase(docBase);
                context.setRealm(this.getHost().getRealm());
                ContextConfig contextConfig = new ContextConfig();
                context.addLifecycleListener(contextConfig);
                String pathToWebXml = docBase + "Store/web.xml";
                if (new File(pathToWebXml).exists()) {
                    contextConfig.setDefaultWebXml(pathToWebXml);
                } else {
                    contextConfig.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML");
                }
                host.addChild(context);
            } catch (Exception e) {
                log.error("Error deploying webapp", e);
            }
            return context;
            
        }
    };
    tomcat.setPort(8081);
    
    Service service = tomcat.getService();
    service.addConnector(sslConnector());
    
    try {
        URL resource = TomcatServer.class.getClassLoader().getResource(".");
        
        tomcat.addWebapp("", resource.getPath());
        //add others here...
    } catch (ServletException e) {
        log.error("Problem webapp. Could be fatal?");
    }
    
    tomcat.start();
    tomcat.getServer().await();
    
}

但这会导致错误,例如:

WARNING: Failed to scan 

[file:/Users/j/.m2/repository/xalan/xalan/2.7.2/xercesImpl.jar] from classloader hierarchy
java.io.IOException: java.lang.reflect.InvocationTargetException
    at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:185)
    at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:65)
    at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:49)
    at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:374)
    at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:309)
    at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:278)
    at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:229)
    at org.apache.catalina.startup.ContextConfig.processJarsForWebFragments(ContextConfig.java:1898)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1131)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:783)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:307)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5212)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.GeneratedConstructorAccessor6.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
    at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:182)
    ... 21 more
Caused by: java.nio.file.NoSuchFileException: /Users/j/.m2/repository/xalan/xalan/2.7.2/xercesImpl.jar
    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at java.base/sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
    at java.base/sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:148)
    at java.base/java.nio.file.Files.readAttributes(Files.java:1843)
    at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1198)
    at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:701)
    at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:240)
    at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:171)
    at java.base/java.util.jar.JarFile.<init>(JarFile.java:347)
    ... 26 more

Jun 23, 2021 2:57:15 PM org.apache.tomcat.util.scan.StandardJarScanner processURLs
WARNING: Failed to scan [file:/Users/j/.m2/repository/xalan/xalan/2.7.2/xml-apis.jar] from classloader hierarchy
java.io.IOException: java.lang.reflect.InvocationTargetException
    at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:185)
    at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:65)
    at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:49)
    at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:374)
    at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:309)
    at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:278)
    at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:229)
    at org.apache.catalina.startup.ContextConfig.processJarsForWebFragments(ContextConfig.java:1898)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1131)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:783)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:307)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5212)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.GeneratedConstructorAccessor6.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
    at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:182)
    ... 21 more
Caused by: java.nio.file.NoSuchFileException: /Users/j/.m2/repository/xalan/xalan/2.7.2/xml-apis.jar
    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at java.base/sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
    at java.base/sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:148)
    at java.base/java.nio.file.Files.readAttributes(Files.java:1843)
    at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1198)
    at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:701)
    at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:240)
    at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:171)
    at java.base/java.util.jar.JarFile.<init>(JarFile.java:347)
    ... 26 more

请注意,目前我是static void main从 Intellij 内部开始的。

这里的方法e()依赖于解析现有的 web.xml 文件,但这不起作用,并且似乎由于缺少类路径内容而失败。

第一种方法c()依赖于尝试复制配置,但我缺少尝试正确复制它的方法。

例如,我无法以相同的方式添加侦听器,并且无法配置例如参数。 session-config

第一个没有类路径问题并启动,但我认为有些事情,比如监听器没有正确设置,也没有触发他们的事件。

编辑1:

也许这是添加侦听器的方式,在c()

 Context ctx = tomcat.addContext(tomcat.getHost(), "/", tmpDir.getAbsolutePath());
    ctx.addApplicationListener(m.Web.startup.Listener.class.getCanonicalName());
    ctx.addApplicationListener(m.Store.Listener.class.getCanonicalName());

但是事情又开始了,但在tomcat中仍然出错。不确定 classpath: ... 在原始web.xml模仿中c()是否也被准确应用。

编辑2:

现在大部分事情都搞定了,但是 WebSockets(在代码中注释)没有被拾取,以及 HttpSessionListener 没有被触发。

web.xml您可以定义一个实现多个接口的侦听器,例如ServletContextListener, HttpSessionListener但使用嵌入式 Tomcat,这似乎不起作用。到目前为止,我也无法单独注册它们,但这应该是可能的。还是很烦。

我只是希望您可以将 web.xml 提供给它,它可以自行配置,就像独立的一样。我不明白为什么要这么难。

private static void c() throws LifecycleException, ServletException, URISyntaxException, DeploymentException, IOException {
    File tmpDir = new File(System.getProperty("java.io.tmpdir"));
                                            
    Tomcat tomcat = new Tomcat();
    tomcat.setBaseDir(tmpDir.getAbsolutePath());
    tomcat.setPort(8080);
    
    Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
    ctx.addApplicationListener(m.Web.startup.Listener.class.getCanonicalName());
    ctx.addApplicationListener(m.Store.Listener.class.getCanonicalName());
    ctx.addApplicationListener(Listener.class.getCanonicalName());
    ctx.setSessionTimeout(30);
    
    Wrapper wrapper = Tomcat.addServlet(ctx, "mmm.com.dispatcher.servlet", m.Web.startup.DispatcherServlet.class.getCanonicalName());
    
    wrapper.addInitParameter("contextClass", org.springframework.web.context.support.XmlWebApplicationContext.class.getCanonicalName());
    wrapper.addInitParameter("contextConfigLocation", """
        classpath:/Web/config/ConfigWeb.xml
        classpath:/Auth/config/ConfigAuth.xml
        classpath:/Assets/config/ConfigAssets.xml
        classpath:/Accounts/config/ConfigAccounts.xml
        classpath:/App/config/ConfigApp.xml
        classpath:/Accounts/config/ConfigAccounts.xml
        classpath:/Store/config/ConfigStore.xml
    """);
    
    wrapper.setLoadOnStartup(1);
    
    if ( true ) {
        wrapper.addMapping("/");
    }
    else if ( false ) {
        ctx.addServletMappingDecoded("/", "mmm.com.dispatcher.servlet", true);
    }
    
    tomcat.start();

    if ( false ) {
        ContainerProvider.getWebSocketContainer().connectToServer(Socket.class, new URI("ws://"));
    }
    
    tomcat.getServer().await();
}
4

0 回答 0