简体   繁体   中英

Using Guice dependency injection in HttpServlet with Kotlin

Im having a trouble with injecting dependencies into my HttpServlet . If I use constructor injection, I get servlet instantiation error, because of absence of empty constructor (even when i use kotlin-noarg plugin). If I use @Inject on lateinit var I get lateinit property name has not been initialized error. What am I doing wrong?

Here is my code:

HomeController.kt

import com.google.inject.Inject
import com.google.inject.Singleton
import com.google.inject.name.Named
import javax.servlet.annotation.WebServlet
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

@Singleton
@WebServlet(name = "Hello", value = ["/hello"])
class HomeController: HttpServlet() {

    @Inject
    @Named("app-url")
    lateinit var name: String

    override fun doGet(req: HttpServletRequest, res: HttpServletResponse) {
        res.writer.write("Hello, $name!")
    }
}

MainModule.kt

class MainModule : Module {

    /**
     * Contributes bindings and other configurations for this module to `binder`.
     */
    override fun configure(binder: Binder) {
        val conf = ConfigFactory.load()

        binder.bind(String::class.java).annotatedWith(Names.named("app-url")).toInstance(conf.getString("appUrl")) // TODO: move to env

    }
}

MyGuiceServletConfig.kt

import com.google.inject.Guice
import com.google.inject.Injector
import com.google.inject.servlet.GuiceServletContextListener

class MyGuiceServletConfig : GuiceServletContextListener() {
    override fun getInjector(): Injector {
        return Guice.createInjector(
                MyServletModule(),
                MainModule()
        )
    }
}

MyServletModule.kt

class MyServletModule: ServletModule() {

    override fun configureServlets() {
        serve("/home").with(HomeController::class.java)
    }
}

webapp/WEB-INF/web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>tj.alif.core.app.guice.MyGuiceServletConfig</listener-class>
    </listener>
</web-app>

Did you already try this?

@JvmField
@Inject
@Named("app-url")
lateinit var name: String

Unforuntately this is only a guess, since I don't have an IDE at hand right now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM