If you use Tomcat Embedded you can force Tomcat to view your Servlet programmatically and not need to edit JEE XML descriptors.
Here is an example below where you do not need to use the @WebServlet
annotation:
Main method
// Para tratar o CTRL-C
final Tomcat tomcat = new Tomcat();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
tomcat.stop();
} catch (LifecycleException e) {
e.printStackTrace();
}
}
});
// inicio
tomcat.setPort(Integer.valueOf(args[0]));
Log containerLogger = context.getLogger();
try {
Context context = tomcat.addWebapp("/",
new File(".").getAbsolutePath());
containerLogger.info("*** INICIANDO ***");
containerLogger.info("*** iniciando o Tomcat com o servlet "
+ MyDynServlet.class.getSimpleName());
tomcat.start();
String myDynServletName = MyDynServlet.class.getSimpleName()
.toLowerCase();
Wrapper myDynServlet = context.createWrapper();
myDynServlet.setName(myDynServletName);
myDynServlet.setServletClass(MyDynServlet.class.getCanonicalName());
myDynServlet.addInitParameter("debug", "0");
myDynServlet.addInitParameter("listings", "false");
myDynServlet.setLoadOnStartup(1);
context.addChild(myDynServlet);
// O mapping do Servlet pode vir de qualquer fonte.
// Abaixo está hard-coded
context.addServletMapping("/mydynservlet", myDynServletName);
// Para ajudar na resolução de problemas listo os mappings
String[] servletMappings = context.findServletMappings();
for (String mapping : servletMappings) {
containerLogger.info("*** ServletMapping " + mapping);
}
} catch (ServletException | LifecycleException e) {
e.printStackTrace();
}
int CINCO_SEGUNDOS = 5 * 1000;
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// Wait until a proper shutdown command is received, then
// cancel timer thread.
containerLogger.info("*** AWAIT Server");
tomcat.getServer().await();
containerLogger.info("*** Server Shutdown Complete ***");
containerLogger.info("*** Cancelando Timer Thread ***");
timer.cancel();
}
}, CINCO_SEGUNDOS);
// Você pode desejar fazer algo depois de carregar o Tomcat em outra Thread.
Note that a Timer Task was created only to not block the current Thread. This is optional.
Maven dependencies:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<tomcat-embed.version>7.0.52</tomcat-embed.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat-embed.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>${tomcat-embed.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>${tomcat-embed.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat-embed.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat7-websocket</artifactId>
<version>${tomcat-embed.version}</version>
</dependency>
</dependencies>
Dependency with Websocket is optional.