Tomcat Catalina 上下文 - 将现有 servlet 添加到上下文 [英] Tomcat Catalina context - add existing servlet to context
问题描述
我想将现有的 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#addContext
和 Tomcat#addWebapp
是后者添加了一些默认的 web.xml
(jsp
和 default
servlet)并扫描 Servlet 3.0 注释和 ServletContainerInitializer
s.
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
配置,你可以通过以下方式获得同样的东西:
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:
- 找到包含您的
Main
类的 JAR 文件或目录, - 将该 JAR 的内容挂载到应用程序的
/WEB-INF/classes
(虚拟)文件夹中(参见 Tomcat 资源):
- Find the JAR file or directory that contains your
Main
class, - 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屋!