Tomcat Catalina 上下文 - 将现有 servlet 添加到上下文 [英] Tomcat Catalina context - add existing servlet to context

查看:63
本文介绍了Tomcat Catalina 上下文 - 将现有 servlet 添加到上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to add an existing servlet to a context and it works, when I use (Main.java):

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

但是,我在 servlet 中有注释来映射 url_pattern(MyServlet.java):

However, I have annotations inside servlet to 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 注释中的映射.

Unfortunately, these annotations do not work. I would like to delete mapping from Main.java and use mapping from my Servlet annotation.

我使用 Tomcat 10.0.0.

I use Tomcat 10.0.0.

Main.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 idea behind embedded Tomcat is to do in code, what the usual Tomcat does through configuration. Therefore the configuration of servlets through annotations is not as straightforward as it is in Tomcat.

您将面临两个问题:

Tomcat#addContextTomcat#addWebapp是后者添加了一些默认的 web.xml(jspdefault servlet)并扫描 Servlet 3.0 注释和 ServletContainerInitializers.

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 ServletContainerInitializers.

如果你不需要或者不想要默认的 web.xml 配置,你可以通过以下方式获得同样的东西:

If you don't need or don't want the default web.xml configuration, you can obtain the same thing with:

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

资源

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

Resources

Even after enabling annotation scanning Tomcat will not find your servlets, because it looks under /WEB-INF/classes of your docBase (which you set to be the current folder). This is a probably empty folder. If you want Tomcat to scan also the classes in your application you'll need to:

  1. 找到包含您的 Main 类的 JAR 文件或目录,
  2. 将该 JAR 的内容挂载到应用程序的 /WEB-INF/classes(虚拟)文件夹中(参见 Tomcat 资源):
  1. Find the JAR file or directory that contains your Main class,
  2. Mount the contents of that JAR to the /WEB-INF/classes (virtual) folder of your application (cf. Tomcat resources):

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();
    }

这篇关于Tomcat Catalina 上下文 - 将现有 servlet 添加到上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆