tipsy
tipsy

Reputation: 402

Servlets/Undertow - Accessing HttpServletRequest and HttpServletResponse

I'm trying to create a simple undertow servlet-server, but I have some problems with undertow wanting to instantiate the servlet. I don't necessarily need to use HttpServlet, I just need access to HttpServletRequest and HttpServletResponse so I can run them through myServicer. What's the best way to achieve this? My current code:

myServicer = ...
undertow = Undertow.builder()
    .addHttpListener(port, host)
    .setHandler(Handlers.path(Handlers.redirect("/")).addPrefixPath("/",
        Servlets.defaultContainer().addDeployment(
            Servlets.deployment()
                .setClassLoader(EmbeddedUndertowServer::class.java.classLoader)
                .setDeploymentName("myDeployment").setContextPath("/")
                .addServlets(Servlets.servlet("myServlet",
                    object : HttpServlet() {
                        override fun service(request: HttpServletRequest, response: HttpServletResponse) {
                            myServicer.service(request, response) // doesn't work
                        }
                    }.javaClass).addMapping("/"))
        ).apply { deploy() }.start()
    ))
    .build()
undertow.start()

This doesn't work because undertow just wants a class, which it tries to instantiate.

Full code/project here: https://github.com/tipsy/javalin/pull/25/files

Upvotes: 1

Views: 1303

Answers (2)

Osmund Francis
Osmund Francis

Reputation: 821

The solution I got is to create a "stub" servlet into which you pass the servicer.

    val servletBuilder = Servlets.deployment()
            .setClassLoader(EmbeddedUndertowServer::class.java.getClassLoader())
            .setContextPath("/")
            .setDeploymentName("javalinDeployment")
            .addServletContextAttribute("javalin-servlet", javalinServlet)
            .addServlets(Servlets.servlet("javalinServlet", UndertowServlet::class.java).addMapping("/"))
    val manager = Servlets.defaultContainer().addDeployment(servletBuilder)
    manager.deploy()
    val httpHandler = manager.start()
    val path = Handlers.path(Handlers.redirect("/")).addPrefixPath("/", httpHandler)
    this.undertow = Undertow.builder().addHttpListener(port, host).setHandler(path).build()
    undertow.start()

The servicer can then be loaded during each servlet initialisation phase:

private var javalinServlet: JavalinServlet? = null

@Throws(ServletException::class)
override fun init(config: ServletConfig) {
    this.config = config
    javalinServlet = config.servletContext.getAttribute("javalin-servlet") as JavalinServlet
}

You can view the changes here: https://github.com/osmundf/javalin-undertow/commit/30487196f2dd7a44d3ef524f642040a7330caf4e

Upvotes: 2

tsolakp
tsolakp

Reputation: 5948

I am not familiar with Undertow but by quick look at their documentation says that it is a application server (web as well) and you can mix Servlet and Undertow handlers together. This most likely means that you either need to use Handler with HttpServerExchange or define a Servlet in order to use HttpServletRequest or HttpServletResponse.

Upvotes: 0

Related Questions