繁体   English   中英

Tomcat Catalina 上下文 - 将现有 servlet 添加到上下文

[英]Tomcat Catalina context - add existing servlet to context

当我使用(Main.java)时,我想将现有的 servlet 添加到上下文中并且它可以工作:

Tomcat.addServlet(ctx, "MyServlet", new MyServlet());
ctx.addServletMappingDecoded("/url_pattern", "MyServlet")

但是,我在 servlet 中有对 map url_pattern(MyServlet.java) 的注释:

@WebServlet(name = "MyServlet", urlPatterns = { "/url_pattern" })
@MultipartConfig(
  fileSizeThreshold = 1024 * 1024 * 1, // 1 MB
  maxFileSize = 1024 * 1024 * 10,      // 10 MB
  maxRequestSize = 1024 * 1024 * 100   // 100 MB
)

不幸的是,这些注释不起作用。 我想从 Main.java 中删除映射并使用我的 Servlet 注释中的映射。

我使用 Tomcat 10.0.0。

主.java

import java.io.File;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;

public class Main {

    public static void main(String[] args) throws LifecycleException,
    InterruptedException {
    Tomcat tomcat = new Tomcat();
    tomcat.setPort(8082);

    Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());

    Tomcat.addServlet(ctx, "MyServlet", new MyServlet());
    
    ctx.setAllowCasualMultipartParsing(true);
    ctx.addServletMappingDecoded("/url_pattern", "MyServlet");
    
    
    tomcat.start();
    tomcat.getConnector();
    }
}

嵌入式 Tomcat 背后的想法是在代码中执行,通常的 Tomcat 通过配置执行。 因此,通过注解配置 servlets 并不像在 Tomcat 中那样简单。

您将面临两个问题:

注释扫描

The main difference between Tomcat#addContext and Tomcat#addWebapp is that the latter adds some default web.xml (the jsp and default servlet) and scans for Servlet 3.0 annotations and ServletContainerInitializer s.

如果您不需要或不想要默认的web.xml配置,您可以通过以下方式获得相同的内容:

Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
ctx..addLifecycleListener(new ContextConfig());

资源

即使启用注释扫描 Tomcat 也不会找到您的 servlets,因为它在您的docBase (您设置为当前文件夹)的/WEB-INF/classes下查找。 这可能是一个空文件夹。 如果您希望 Tomcat 也扫描应用程序中的类,您需要:

  1. 找到包含您的Main class 的 JAR 文件或目录,
  2. 将 JAR 的内容挂载到应用程序的/WEB-INF/classes (虚拟)文件夹(参见Tomcat 资源):
public static void main(String[] args) throws LifecycleException, InterruptedException {
   ...
   // Add the JAR/folder containing this class to PreResources
   final WebResourceRoot root = new StandardRoot(ctx);
   final URL url = findClassLocation(Main.class);
   root.createWebResourceSet(ResourceSetType.PRE, "/WEB-INF/classes", url, "/");
   ctx.setResources(root);
   ...
}

/*
 * Tries to find the URL of the JAR or directory containing {@code clazz}.
 */
private static URL findClassLocation(Class< ? > clazz) {
    final ClassLoader cl = Main.class.getClassLoader();
    if (cl instanceof URLClassLoader) {
        final URLClassLoader urlCl = (URLClassLoader) cl;
        final String mainClassName = clazz.getName().replaceAll("\\.", "/") + ".class";
        final String mainResource = urlCl.findResource(mainClassName)//
                                         .toString();
        for (final URL url : urlCl.getURLs()) {
            if (mainResource.toString().startsWith(url.toString())) {
                return url;
            }
        }
    }
    throw new RuntimeException("Didn't find the URL of the Main class.");
}

概括

最后你会得到:

    public static void main(String[] args) throws LifecycleException {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8082);
        final Context ctx = tomcat.addContext("", Paths.get(".").toAbsolutePath().toString());
        // Add the standard ContextConfig, which scans for annotations
        ctx.addLifecycleListener(new ContextConfig());
        // Add the JAR/folder containing this class to PreResources
        final WebResourceRoot root = new StandardRoot(ctx);
        final URL url = findClassLocation(Main.class);
        root.createWebResourceSet(ResourceSetType.PRE, "/WEB-INF/classes", url, "/");
        ctx.setResources(root);
        // Run Tomcat
        tomcat.getConnector();
        tomcat.start();
        tomcat.getServer().await();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM