Tomcat Catalina 上下文 - 将现有的 servlet 添加到上下文
Tomcat Catalina context - add existing servlet to context
我想将现有的 servlet 添加到上下文中,当我使用 (Main.java):
时它可以工作
Tomcat.addServlet(ctx, "MyServlet", new MyServlet());
ctx.addServletMappingDecoded("/url_pattern", "MyServlet")
但是,我在 servlet 中有注释来映射 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 注释中的映射。
我用的是Tomcat10.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 通过配置完成。因此通过注解配置servlet并不像在Tomcat.
中那么简单
您将面临两个问题:
注释扫描
Tomcat#addContext
and Tomcat#addWebapp
之间的主要区别是后者添加了一些默认 web.xml
(jsp
和 default
servlet)并扫描 Servlet 3.0 注释和 ServletContainerInitializer
s.
如果您不需要或不想要默认的 web.xml
配置,您可以通过以下方式获得同样的东西:
Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
ctx.addLifecycleListener(new ContextConfig());
资源
即使在启用注释扫描后,Tomcat 也不会找到您的 servlet,因为它会在您的 docBase
(您设置为当前文件夹)的 /WEB-INF/classes
下查找。这可能是一个空文件夹。如果您希望 Tomcat 也扫描您应用程序中的 classes,您需要:
- 找到包含您的
Main
class, 的 JAR 文件或目录
- 将该 JAR 的内容安装到应用程序的
/WEB-INF/classes
(虚拟)文件夹中(参见 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) {
return clazz.getProtectionDomain().getCodeSource().getLocation();
}
总结
最后你会得到:
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();
}
我想将现有的 servlet 添加到上下文中,当我使用 (Main.java):
时它可以工作Tomcat.addServlet(ctx, "MyServlet", new MyServlet());
ctx.addServletMappingDecoded("/url_pattern", "MyServlet")
但是,我在 servlet 中有注释来映射 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 注释中的映射。
我用的是Tomcat10.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 通过配置完成。因此通过注解配置servlet并不像在Tomcat.
中那么简单您将面临两个问题:
注释扫描
Tomcat#addContext
and Tomcat#addWebapp
之间的主要区别是后者添加了一些默认 web.xml
(jsp
和 default
servlet)并扫描 Servlet 3.0 注释和 ServletContainerInitializer
s.
如果您不需要或不想要默认的 web.xml
配置,您可以通过以下方式获得同样的东西:
Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
ctx.addLifecycleListener(new ContextConfig());
资源
即使在启用注释扫描后,Tomcat 也不会找到您的 servlet,因为它会在您的 docBase
(您设置为当前文件夹)的 /WEB-INF/classes
下查找。这可能是一个空文件夹。如果您希望 Tomcat 也扫描您应用程序中的 classes,您需要:
- 找到包含您的
Main
class, 的 JAR 文件或目录
- 将该 JAR 的内容安装到应用程序的
/WEB-INF/classes
(虚拟)文件夹中(参见 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) {
return clazz.getProtectionDomain().getCodeSource().getLocation();
}
总结
最后你会得到:
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();
}