Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded Jetty with annotated servlet patterns?

The following working code demonstrates including two servlets into an embedded instance of jetty.

Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(new ServletHolder(new Html()), "/html");
context.addServlet(new ServletHolder(new Iphone()), "/iphone");       
server.setHandler(context);
server.start();
server.join();

How should this be altered so that instead of using the url "/iphone", it would use the urlpatterns in the annotation of the servlet, ie

@WebServlet(urlPatterns={"/json", "/iphone"})
public class Iphone extends HttpServlet {
    ....
}
like image 200
Jay Avatar asked Dec 19 '12 12:12

Jay


1 Answers

The servlets are on your server's classpath rather than packaged in a WAR.

Servlet 3.0 specification states:

In a web application, classes using annotations will have their annotations processed only if they are located in the WEB-INF/classes directory, or if they are packaged in a jar file located in WEB-INF/lib within the application.

The web application deployment descriptor contains a new “metadata-complete” attribute on the web-app element. The “metadata-complete” attribute defines whether the web descriptor is complete, or whether the class files of the jar file should be examined for annotations and web fragments at deployment time. If “metadata-complete” is set to "true", the deployment tool MUST ignore any servlet annotations present in the class files of the application and web fragments. If the metadata-complete attribute is not specified or is set to "false", the deployment tool must examine the class files of the application for annotations, and scan for web fragments.

You may have to look at packaging a WAR and using a context with more features like WebAppContext.

Alternatively, you might try your own annotation scanning. Something of the form:

void registerServlets(ServletContextHandler context,
                              Class<? extends HttpServlet> type)
          throws InstantiationException, IllegalAccessException,
                 InvocationTargetException, NoSuchMethodException {
    WebServlet info = type.getAnnotation(WebServlet.class);
    for (String pattern : info.urlPatterns()) {
        HttpServlet servlet = type.getConstructor().newInstance();
        context.addServlet(new ServletHolder(servlet), pattern);
    }
}
like image 85
McDowell Avatar answered Oct 24 '22 08:10

McDowell