我正在努力学习如何动态添加一些web服务。我正在使用Scalatra作为Web服务框架。
我希望允许开发人员能够更改身份验证,例如,不要使用硬编码凭据,而是使用数据库或密码文件或他们需要的任何内容。
我还想让他们在servlet中添加新的webservices。
所以,我想要做的是在引导代码中加载它并重新编译该类然后使用该版本。
我看过这个,但我需要重新编译整个课程,而不是片段。
Generating a class from string and instantiating it in Scala 2.10
这是我尝试过的,但是我添加了一个“/ help”webservice,但是找不到它,所以新类还没有被使用。
class ScalatraBootstrap extends LifeCycle {
override def init(context: ServletContext) {
val sourceDir = new java.io.File("C:/Temp/MyServlet.scala")
val sse = ScalaScriptEngine.onChangeRefresh(sourceDir)
sse.refresh
println("*** - " + sse.compilationStatus.startTime + " " + sse.compilationStatus.stopTime)
context.mount(sse.get[MyServlet]("test.proj.MyServlet"), "/*")
我目前正在使用scalascriptengine(https://code.google.com/p/scalascriptengine/)。
那么,当它可能在同一个文件中有案例类,注释和对象类时,如何动态地重新编译web服务的类文件?
我想知道我是否需要在Groovy中使用web服务,但我希望保持其功能。
更新
我首先考虑过插件,但遇到了如何以这种方式添加新的web服务的问题,可能是Scalatra不是正确的选择,我可能需要更改我的REST服务框架
最终,我希望能够在不必重新启动应用程序的情况下即时更改Web服务,并且重新编译源代码将允许这样做。
答案 0 :(得分:1)
实现插件的可供性并不是太难,至少在相当简单的情况下。基本要素是:
java.lang.Class[P <: PlugInType]
的实例,只要你不需要构造函数参数就可以获得一个实例。答案 1 :(得分:0)
感谢@RandallSchultz,我找到了一个有效的解决方案。
override def init(context: ServletContext) {
val sourceDir = new java.io.File("C:/Temp/HelpServlet.scala")
val sse = ScalaScriptEngine.onChangeRefresh(sourceDir)
sse.refresh
println("*** - " + sse.compilationStatus.startTime + " " + sse.compilationStatus.stopTime)
context.mount(new MyServlet, "/*")
context.mount(sse.get("org.myproject.rest.HelpServlet"), "/help/*")
所以当我去&#34; / help / help&#34;我按预期获得了帮助页面,因此添加了新的Web服务。
通过从文件中读取它,我可以在应用程序运行时添加它。